How to shallow test a component with an `entryComponents`?

My solutions is base on @kampsj solution, but I think is cleaner.

TestBed create a dynamic module. So, we can use a module that has the entryComponents ( nothing new ). My difference is that I don't create a testModule, I just import the module where this Component belongs, and is cleaner because you don't need to add anything else ( service, other components, etc.). This should implies if ng serve works then ng test should ( at least from the creation component perspective).

Suppose we have the follow structure:

app
├--- app.module.ts
├--- app.component.ts
├--- ...
├--- SomeModule2
|    ├--- somemodule2.module.ts
|    ├--- componentThatCreateDynamicsComponents
|         ├--- componentThatCreateDynamicsComponents.component.ts
|         ├--- componentThatCreateDynamicsComponents.html
|         ├--- componentThatCreateDynamicsComponents.component.spec.ts
|    ├--- someCOmponent
|         ├--- someCOmponent.component.ts
|         ├--- someCOmponent.html
|         ├--- someCOmponent.component.spec.ts

The TestBed of componentThatCreateDynamicsComponents.component.spec.ts should import somemodule2 from somemodule2.module.ts. In case that you don't split your project into modules, should be the unique module that you have.

Is true that you will have Component that you don't use in that test, but it doesn't matter because is just test. And you gain flexibility when you change you testing module.


They plan on adding EntryComponents to the testing module interface. See issue: https://github.com/angular/angular/issues/10760

For a current workaround see the Angular Material library see https://github.com/angular/components/blob/master/src/material/dialog/dialog.spec.ts#L1660.

Basically, they create a real module on the fly and then import it for the tests.

// Create a real (non-test) NgModule as a workaround for
// https://github.com/angular/angular/issues/10760
const TEST_DIRECTIVES = [
  ComponentWithChildViewContainer,
  PizzaMsg,
  DirectiveWithViewContainer,
  ContentElementDialog
];

@NgModule({
  imports: [MdDialogModule],
  exports: TEST_DIRECTIVES,
  declarations: TEST_DIRECTIVES,
  entryComponents: [ComponentWithChildViewContainer, PizzaMsg, ContentElementDialog],
})
class DialogTestModule { }

Now you can use DialogTestModule

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [MdDialogModule.forRoot(), DialogTestModule]
      ...

Tags:

Angular