Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular Testbed overrideModule not working

When using the following configuration for a test fixture, I get complaints that the tag cannot be found. Substituting the MockSelectionToolComponent directly in AppModule works fine, so must be something else...

 // Add the imported module to the imports array in beforeEach
    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [MockSelectionToolComponent],
            imports: [

                AppModule
            ]
        }).overrideModule(AppModule, {
            remove: {
                declarations: [SelectionToolComponent]
            }
        }).compileComponents();

        fixture = TestBed.createComponent(MappingComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
        component.initialiseMap();
    });

Error: Template parse errors: 'app-selection-tool' is not a known element:

like image 617
jenson-button-event Avatar asked Jun 26 '17 10:06

jenson-button-event


People also ask

What can I use instead of TestBed?

TestBed.get() was deprecated as of Angular version 9. To help minimize breaking changes, Angular introduces a new function called TestBed.inject() , which you should use instead.

What does TestBed do in Angular?

TestBedlink. Configures and initializes environment for unit testing and provides methods for creating components and services in unit tests.

What does TestBed createComponent do?

TestBed. createComponent() creates an instance of the BannerComponent , adds a corresponding element to the test-runner DOM, and returns a ComponentFixture . Do not re-configure TestBed after calling createComponent .

Does fixture detectChanges call ngOnInit?

fixture. detectChanges() tells Angular to run change-detection. Finally! Every time it is called, it updates data bindings like ng-if, and re-renders the component based on the updated data. Calling this function will cause ngOnInit to run only the first time it is called.


2 Answers

So in fact we don't add it to the test module's declaration, but to the original Module:

// Add the imported module to the imports array in beforeEach
beforeEach(() => {
    TestBed.configureTestingModule({
        declarations: [],
        imports: [

            AppModule
        ]
    }).overrideModule(AppModule, {
        remove: {
                declarations: [SelectionToolComponent]
            },
        add: {
                declarations: [MockSelectionToolComponent]
        }
    }).compileComponents();

    fixture = TestBed.createComponent(MappingComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    component.initialiseMap();
});

Good luck finding that documented anywhere.

like image 120
jenson-button-event Avatar answered Oct 25 '22 16:10

jenson-button-event


As you stated, it's not possible to directly declare the overrides, but do it in a chained overriding Method. You can also use the set syntax, in component here for example, applies also for module.

    TestBed.configureTestingModule({
        imports: [RouterTestingModule],
        declarations: [MockProductCardComponent, ProductListComponent]
        })
        .overrideComponent(ProductListComponent, {
            set: {
                providers: [
                    { provide: ActivatedRoute, useValue: { fragment: Observable.of(fragment) }},
                    { provide: PageScrollService, useClass: MockPageScrollService }
                ]
            }
        })
like image 40
Markus Avatar answered Oct 25 '22 17:10

Markus