You already saw how to use Material MatDialog in Angular. In this tutorial, you’ll learn how to unit test components having Material MatDialog.
Source code from this tutorial is available at GitHub.
You can also follow the video tutorial on YouTube.
Running Angular Unit Tests
For the sake of this tutorial , you’ll clone the source code from the Angular Material MatDialog tutorial.
git clone https://github.com/jay3dec/upgraded-winner
cd upgraded-winner
npm install
npm start
You’ll have the Angular application running.
Stop the Angular application server. From the project directory, using the Angular CLI command, let’s run the default unit test cases.
ng test --code-coverage
--code-coverage
options let’s you see the code coverage.
Once the unit test cases are executed, it will show the following results.
TOTAL: 4 FAILED, 0 SUCCESS
TOTAL: 4 FAILED, 0 SUCCESS
TOTAL: 4 FAILED, 0 SUCCESS
Adding MatDialog Dependencies
You will getting the following dependency error related to MatDialog
, NullInjectorError: No provider for MatDialog!
You have two components in the Angular application, AppComponent
and PopUpComponent
. Since AppComponent
is using the MatDialog
let’s add the dependency to app.component.spec.ts
file.
Import MatDialogModule
to the app.component.spec.ts
and also remove the last unit test case, since it’s irrelevant to our code.
import { TestBed, async } from '@angular/core/testing';
import { MatDialogModule } from '@angular/material/dialog';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
MatDialogModule
],
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'angular-mateiral'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('angular-mateiral');
});
});
Now there is one more dependency failure related to MatDialogData
in PopupComponent
.
NullInjectorError: No provider for InjectionToken MatDialogData!
Let’s add a provider for the same in pop-up.component.spec.ts
file.
providers : [{
provide : MAT_DIALOG_DATA,
useValue : {}
}]
Here is how the complete pop-up.component.spec.ts
file looks :
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { PopUpComponent } from './pop-up.component';
describe('PopUpComponent', () => {
let component: PopUpComponent;
let fixture: ComponentFixture<PopUpComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PopUpComponent ],
providers : [{
provide : MAT_DIALOG_DATA,
useValue : {}
}]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PopUpComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Save the above changes and the unit test cases should run fine without any dependency errors.
Unit Testing Component With MatDialog
Let’s add a new unit test case for testing the openDialog
method which utilizes the MatDialog
instance to show the modal popup.
In app.component.spec.ts
file let’s add a new unit test case as shown:
it('should call openDialog', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
app.openDialog();
})
Using the app instance you are triggering the openDialog
method. Now the app HTML should have the popup HTML. So, let’s try to get the popup HTML and check it to have the expected header title.
it('should call openDialog', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
const expected_header = "Welcome Samuel";
app.openDialog();
fixture.detectChanges();
const popUpHeader = document.getElementsByTagName('h2')[0] as HTMLHeadElement;
expect(popUpHeader.innerText).toEqual(expected_header);
})
As seen in the above code, fixture.detectChanges
helps to detect the changes once the openDialog
method has been called.
Save the above changes and run the unit test cases and you will be able to that it passes successfully.
Chrome 90.0.4430.85 (Windows 10): Executed 4 of 4 SUCCESS (0.082 secs / 0.071 secs)
TOTAL: 4 SUCCESS
TOTAL: 4 SUCCESS
TOTAL: 4 SUCCESS
=============================== Coverage summary ===============================
Statements : 100% ( 12/12 )
Branches : 100% ( 0/0 )
Functions : 100% ( 4/4 )
Lines : 100% ( 10/10 )
================================================================================
Wrapping it up
In this tutorial, you learnt how to write unit test cases for Angular components with MatDialog
. You also learnt how to resolve the following dependency issues,
NullInjectorError: No provider for MatDialog!
NullInjectorError: No provider for InjectionToken MatDialogData!
while running MatDialog
containing unit test cases.
Source code from this tutorial is available at GitHub.