Testing Angular components containing MdDialog

pascal.brokmeier
Mar 22, 2017 · 2 min read

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:

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.

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

spyOn(component.dialog, ‘open’).and.callThrough();

we do

//create a mock MdDialogRef
let mockDialogRef = new MdDialogRef(new OverlayRef(null,null,null,null),{});
//and give it an empty version of our component. alternatively, a stub
mockDialogRef.componentInstance = new OfferFormDialogComponent(null, null);
spyOn(component.dialog, 'open').and.returnValue(mockDialogRef);

and later in the test spec

it('should open the dialog on clicking the button', fakeAsync(() => {
expect(component.dialog.open).toHaveBeenCalledTimes(0);
clickAddNewButton(component, fixture);
fixture.detectChanges();
tick();
expect(component.dialog.open).toHaveBeenCalled();
}));

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
Tests
Component

curiouscaloo

Anything about technology and where our society and technology is heading towards

pascal.brokmeier

Written by

Software Developer, Tech enthusiast, student, board sports and food lover

curiouscaloo

Anything about technology and where our society and technology is heading towards

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade