When testing a component that dynamically opened a dialog using Angular Material (2), I was getting an error I didn’t immediately expect. The MdDialogModule was added to the imports, so my TestBed knew what was going on but my dynamically loaded Component caused problems.

Error: Error in ./AdminHomeComponent class AdminHomeComponent – inline template:21:24 caused by: No component factory found for OfferFormDialogComponent. Did you add it to @NgModule.entryComponents?

Okay, researching the problem online gave me an issue on Github for the angular repository. It suggested the following in the beforeEach block:

[code language=“javascript“]

TestBed.overrideModule(BrowserDynamicTestingModule, {
set: {
entryComponents: [OfferFormDialogComponent],


Sure, this solved the problem but it then causes an actual dialog to be opened during our tests. Well I really just want to test if the framework class gets called. I don’t want to test if the framework actually does what it promises.

Screen Shot 2017-03-21 at 17.46.10
The tests and the created but uninvited dialog

It turns out, the solution is much cleaner, if you just mock instead of actually calling the MDDialog method.

So instead of

[code language=“javascript“]
spyOn(component.dialog, ‚open‘).and.callThrough();

we do

[code language=“javascript“]
let mockDialogRef = new MdDialogRef(new OverlayRef(null,null,null,null),{});
mockDialogRef.componentInstance = new OfferFormDialogComponent(null, null);
spyOn(component.dialog, ‚open‘).and.returnValue(mockDialogRef);

and later in the test spec

[code language=“javascript“]
it(’should open the dialog on clicking the button‘, fakeAsync(() => {
clickAddNewButton(component, fixture);

This way, a clean test of the component without too many dependency is possible. Yes, I am creating a new instance of my OfferFormDialogComponent, but since its constructor doesn’t do anything anyways, and its not active itself, it’s OK.

The whole test and class can be found on github/gist

Write A Comment