angular: TestBed overrideModule doesn't work in ivy

🐞 bug report

Affected Package

The issue is caused by package angular/core

Is this a regression?

Yes, the previous version in which this bug was not present was: 9.0.0-rc.1 without ivy.

Description

I want to mock a child component in the parent component unit test by overriding.

child component:

@Component({
  selector: 'test-cmp',
  template: `<div>some text</div>`
})
export class TestComponent {
  testField = 'default';
}

parent component:

@Component({
  selector: 'app-root',
  template: `<test-cmp #testCmpCtrl></test-cmp>`,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  @ViewChild('testCmpCtrl', {static: true}) testCmpCtrl: TestComponent;
}

parent component unit test:

@Component({
  selector: 'test-cmp',
  template: ``
})
class MockedTestComponent {
  testField = 'overwritten';
}

describe('AppComponent', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [AppModule],
    }).overrideModule(TestModule, {
      remove: { declarations: [TestComponent], exports: [TestComponent] },
      add: { declarations: [MockTestComponent], exports: [MockTestComponent] }
    });
  });

  it('issue example', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;

    expect(app.testCmpCtrl.testField).toBe('overwritten');
  });
});

Without ivy the test works correct, but with ivy the test fails with error: “Error: Expected ‘default’ to be ‘overwritten’”, which means that the override has not occurred.

🔬 Minimal Reproduction

github: https://github.com/nmatushevskiy/ivy-overrideModule-issue

🌍 Your Environment

Angular CLI: 9.0.0-rc.1 Node: 10.16.0 OS: darwin x64 Angular: 9.0.0-rc.1 … animations, cli, common, compiler, compiler-cli, core, forms … language-service, platform-browser, platform-browser-dynamic … router

Package Version

@angular-devkit/architect 0.900.0-rc.1 @angular-devkit/build-angular 0.900.0-rc.1 @angular-devkit/build-optimizer 0.900.0-rc.1 @angular-devkit/build-webpack 0.900.0-rc.1 @angular-devkit/core 9.0.0-rc.1 @angular-devkit/schematics 9.0.0-rc.1 @ngtools/webpack 9.0.0-rc.1 @schematics/angular 9.0.0-rc.1 @schematics/update 0.900.0-rc.1 rxjs 6.5.3 typescript 3.6.4 webpack 4.41.2

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 2
  • Comments: 19 (10 by maintainers)

Most upvoted comments

@kirillNikolaichuk, the built packages should be in dist/packages-dist/... (not dist/packages/...).

But, there is an even better option 🎉 Recently, we made sure all PRs publish their build artifacts, so anyone can grab them from CI and verify the change in a local project. You can read more about it here.

I.e., you can head over to the latest publish_packages_as_artifacts job for PR #33787 and get the build artifacts from the “Artifacts” tab: artifacts

Your variant really work. But if wrap this into beforeEach

beforeEach(() => {
    // 4. TestBed setup...
    TestBed.configureTestingModule({imports: [AppModule]});

    // 5. Override module step...
    TestBed.overrideModule(TestModule, {
      remove: {declarations: [TestComponent], exports: [TestComponent]},
      add: {declarations: [MockTestComponent], exports: [MockTestComponent]}
    });
  });

This variant wouldn’t work.

“It’s be great if we can repro the problem where Components/Modules are packaged in a single test - it’s simplify further investigation” - done