Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests on standalone component fails after update to 14.12.0 #7490

Open
LPCmedia opened this issue Nov 19, 2023 · 10 comments
Open

Tests on standalone component fails after update to 14.12.0 #7490

LPCmedia opened this issue Nov 19, 2023 · 10 comments
Assignees
Labels
bug Something isn't working

Comments

@LPCmedia
Copy link

Description of the bug

Tests fail after updating to 14.12.0
this is for a standalone component using angular 17 for a standalone component.

works with 14.11.0

An example: the following test runs fine in 14.11.0 but fails in 14.12.0

import { TestBed } from '@angular/core/testing';
import { APT_INSTALL_API_CONFIGURATION } from '@apt/api-configuration';
import { AppComponent } from './app.component';
import { MockBuilder } from 'ng-mocks';
import { provideMockStore } from '@ngrx/store/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { TranslocoModule } from '@ngneat/transloco';

describe('AppComponent', () => {
  beforeEach(() => {
    return MockBuilder(AppComponent)
      .keep(AppComponent)
      .mock(TranslocoModule)
      .provide({
        provide: APT_INSTALL_API_CONFIGURATION,
        useValue: {
          host: 'foo.com',
          basePrefix: '/',
          port: 1,
        },
      })
  });

  beforeEach(async () => {
    TestBed.configureTestingModule({
      imports: [AppComponent, RouterTestingModule],
      providers: [provideMockStore({})]
    });
  });

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });
});


Expected vs actual behavior

Expected: the test passes.

Actual :

   Summary of all failing tests
    FAIL  src/app/app.component.spec.ts
     ● AppComponent › should create the app
   
       TypeError: Cannot read properties of undefined (reading 'onRoot')
   
         at m (../../../webpack:/ng-mocks/libs/ng-mocks/src/lib/mock-builder/promise/init-ng-modules.ts:79:7)
         at cnfDef (../../../webpack:/ng-mocks/libs/ng-mocks/src/lib/mock-builder/promise/init-ng-modules.ts:87:26)
         at t.default (../../../webpack:/ng-mocks/libs/ng-mocks/src/lib/mock-builder/promise/init-ng-modules.ts:124:30)
         at t.e.build (../../../webpack:/ng-mocks/libs/ng-mocks/src/lib/mock-builder/mock-builder.promise.ts:96:9)
         at t.build (../../../node_modules/ng-mocks/index.js:1:61713)
         at ../../../node_modules/ng-mocks/index.js:1:69656
         at new ZoneAwarePromise (../../../node_modules/zone.js/bundles/zone.umd.js:1339:25)
         at t.<anonymous> (../../../webpack:/ng-mocks/libs/ng-mocks/src/lib/mock-builder/mock-builder.promise.ts:203:26)
         at ../../../node_modules/ng-mocks/index.js:1:65036
         at Object.next (../../../node_modules/ng-mocks/index.js:1:65141)
         at ../../../node_modules/ng-mocks/index.js:1:64032
         at new ZoneAwarePromise (../../../node_modules/zone.js/bundles/zone.umd.js:1339:25)
         at n (../../../node_modules/ng-mocks/index.js:1:63777)
         at t.beforeCC [as then] (../../../node_modules/ng-mocks/index.js:1:69503)
         at t.<anonymous> (../../../webpack:/ng-mocks/libs/ng-mocks/src/lib/mock-builder/mock-builder.performance.ts:67:37)
         at ../../../node_modules/ng-mocks/index.js:1:60609
         at Object.next (../../../node_modules/ng-mocks/index.js:1:60714)
         at ../../../node_modules/ng-mocks/index.js:1:59605
         at new ZoneAwarePromise (../../../node_modules/zone.js/bundles/zone.umd.js:1339:25)
         at this (../../../node_modules/ng-mocks/index.js:1:59350)
         at t.then (../../../webpack:/ng-mocks/libs/ng-mocks/src/lib/mock-builder/mock-builder.performance.ts:46:18)
   
   
   Test Suites: 1 failed, 38 passed, 39 total
   Tests:       1 failed, 98 passed, 99 total
   Snapshots:   0 total
   Time:        24.293 s
   Ran all test suites.
@LPCmedia LPCmedia added the bug Something isn't working label Nov 19, 2023
@satanTime
Copy link
Member

Hi @LPCmedia, could you create a min example with the failure?

I cannot reproduce on my side:

import { TestBed } from '@angular/core/testing';
import { MockBuilder } from 'ng-mocks';
import { provideMockStore } from '@ngrx/store/testing';
import { RouterTestingModule } from '@angular/router/testing';
import {provideTranslocoScope, TranslocoModule} from '@ngneat/transloco';
import {Component, InjectionToken} from "@angular/core";

const APT_INSTALL_API_CONFIGURATION = new InjectionToken('APT_INSTALL_API_CONFIGURATION');

@Component({
  selector: 'target',
  standalone: true,
  imports: [TranslocoModule],
  providers: [provideTranslocoScope({
    scope: 'core',
  })],
  template: `
    <nav *transloco="let t">
      <span>{{ t('core.test') }}</span>
    </nav>
  `,
})
class AppComponent {}

describe('AppComponent', () => {
  beforeEach(() => {
    return MockBuilder(AppComponent)
      .keep(AppComponent)
      .mock(TranslocoModule)
      .provide({
        provide: APT_INSTALL_API_CONFIGURATION,
        useValue: {
          host: 'foo.com',
          basePrefix: '/',
          port: 1,
        },
      })
  });

  beforeEach(() => TestBed.configureTestingModule({
      imports: [AppComponent, RouterTestingModule],
      providers: [provideMockStore({})]
    }).compileComponents()
  );

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });
});

@satanTime
Copy link
Member

Also, could you check if this change solves the issue? ng-mocks.zip

@satanTime
Copy link
Member

And this should help to understand which module is causing the issue: ng-mocks.zip

@LPCmedia
Copy link
Author

I don't seem to have the issue with your second zip. The spec passes now and this is the output:

  ● Console
       
           console.log
             isExportedOnRoot _CommonModule
       
             at isExportedOnRoot (../../../node_modules/ng-mocks/index.js:5791:17)
       
           console.log
             init-ng-modules _CommonModule
       
             at ../../../node_modules/ng-mocks/index.js:5853:25
       
           console.log
             isExportedOnRoot _CommonModule
       
             at isExportedOnRoot (../../../node_modules/ng-mocks/index.js:5791:17)
             
             

Let me know if the repro is still needed for this bug ?

I may get to it tonight anyway as I am having unrelated issues with a NullInjectorError with an ngrx store following examples on the site with a renderFactory.

@satanTime
Copy link
Member

aha.... interesting... it would be great to get an example with a failure on the current version.

I'll release the fix now, but the issue is I don't know how to cover it with tests.

@satanTime
Copy link
Member

The fix: #7492

@LPCmedia
Copy link
Author

Fix works well thanks. And of course the repro is not reproducing....Its hard to reproduce everything in our private code base including the re-adding all the jest transforms and other fun configuration we need to add.

Let me know if you want to track under a separate issue. I will keep you posted should I find something, but I suspect that in the ngrx case we have some meta-reducer's at play that are may cause some strange behaviours.

      NullInjectorError: No provider for _Store!

      at NullInjector.get (../../../node_modules/@angular/core/fesm2022/core.mjs:5601:27)
      at R3Injector.slice (../../../node_modules/@angular/core/fesm2022/core.mjs:6044:33)
      at R3Injector.prop (../../../webpack:/ng-mocks/libs/ng-mocks/src/lib/common/ng-mocks-global-overrides.ts:378:33)
      at R3Injector.get (../../../webpack:/ng-mocks/libs/ng-mocks/src/lib/mock-service/helper.create-clone.ts:17:59)
      at R3Injector.slice (../../../node_modules/@angular/core/fesm2022/core.mjs:6044:33)
      at R3Injector.prop (../../../webpack:/ng-mocks/libs/ng-mocks/src/lib/common/ng-mocks-global-overrides.ts:378:33)
      at R3Injector.get (../../../webpack:/ng-mocks/libs/ng-mocks/src/lib/mock-service/helper.create-clone.ts:17:59)
      at _TestBedImpl.inject (../../../node_modules/@angular/core/fesm2022/testing.mjs:1844:62)
      at Function.inject (../../../node_modules/@angular/core/fesm2022/testing.mjs:1697:37)
      at src/app/shared/components/helpline-numbers/helpline-numbers.component.spec.ts:44:27
      at fakeAsyncFn (../../../node_modules/zone.js/bundles/zone-testing.umd.js:2083:34)
      at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (../../../node_modules/zone.js/bundles/zone.umd.js:411:30)
      at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (../../../node_modules/zone.js/bundles/zone-testing.umd.js:300:43)
      at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (../../../node_modules/zone.js/bundles/zone.umd.js:410:56)
      at Zone.Object.<anonymous>.Zone.run (../../../node_modules/zone.js/bundles/zone.umd.js:165:47)
      at Object.wrappedFunc (../../../node_modules/zone.js/bundles/zone-testing.umd.js:789:34)```

@satanTime
Copy link
Member

satanTime commented Nov 20, 2023

Hi there,

unfortunately, without clear guidance how the issue appears, it's hard to track it.

With isExportedOnRoot _CommonModule, I can try to find a way to produce it.
However, for NullInjectorError: No provider for _Store! looks like a normal failure when injector tries to get a service which wasn't defined in TestBed.

I would suggest to change approach of calling MockBuilder and TestBed.configureTestingModule for the same test, because both of them have create independent contexts, and it can easily lead to missed injection.
The right way would be something like that:

  beforeEach(() => {
    return MockBuilder([AppComponent, RouterTestingModule], [TranslocoModule])
      .provide(provideMockStore({}))
      .provide({
        provide: APT_INSTALL_API_CONFIGURATION,
        useValue: {
          host: 'foo.com',
          basePrefix: '/',
          port: 1,
        },
      })
  });

instead of

  beforeEach(() => {
    return MockBuilder(AppComponent)
      .keep(AppComponent)
      .mock(TranslocoModule)
      .provide({
        provide: APT_INSTALL_API_CONFIGURATION,
        useValue: {
          host: 'foo.com',
          basePrefix: '/',
          port: 1,
        },
      })
  });

  beforeEach(() => TestBed.configureTestingModule({
      imports: [AppComponent, RouterTestingModule],
      providers: [provideMockStore({})]
    }).compileComponents()
  );

@LPCmedia
Copy link
Author

Thanks, Im am closing this ticket.
FYI what was missing and made the rxjs test was the return statement on MockBuilder. 🤦

@satanTime
Copy link
Member

Aha, that's good.

I'll keep it open to cover _CommonModule somehow in the future.

@satanTime satanTime reopened this Nov 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants