I have a DialogComponent that has the following constructor where Dialog is a custom object:

constructor( public dialogRef: MatDialogRef<CustomDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: Dialog ) 

I created the following TestBed in Angular4:

data = new Dialog() data.message = 'Dialog Message' TestBed.configureTestingModule({ imports: [MaterialModules], declarations: [CustomDialogComponent], providers: [MatDialogRef, { provide: Dialog, useValue: data }] }) TestBed.overrideModule(BrowserDynamicTestingModule, { set: { entryComponents: [CustomDialogComponent] } }) await TestBed.compileComponents() 

But I get the following error:

Failed: Can't resolve all parameters for MatDialogRef: (?, ?, ?). Error: Can't resolve all parameters for MatDialogRef: (?, ?, ?). 

changing providers to:

providers: [ { provide: MatDialogRef, useValue: {} }, { provide: MAT_DIALOG_DATA, useValue: data } ] 

results in the following error:

Error: No provider for Dialog! 

How do I resolve this?

2

5 Answers

I solved it by changing the component constructor to:

constructor( public dialogRef: MatDialogRef<CustomDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: Dialog | any ) 

The providers in the TestBed were:

providers: [{ provide: MatDialogRef, useValue: {} }, { provide: MAT_DIALOG_DATA, useValue: data }] 
4

If you use at least one MatDialogRef method, you should create a mock. For example I use the close() method. Without it errors would be generated so I made the below class with an empty method.

export class MatDialogRefMock { close(value = '') { } } 

and use that instead of an empty value, with useClass

{ provide: MatDialogRef, useClass: MatDialogRefMock }, 
2

Import MatDialogModule and MatDialogRef from angular/material/dialog instead of angular/material. Import the ModalDialogModule and provide providers for MatDialogRef in your TestBed.

Import {MatdialogModule,MatDialogRef} from '@angular/material/dialog'; TestBed.configureTestingModule({ declarations: [componentName], imports: [MatdialogModule], providers: [{provide : MatDialogRef, useValue : {}}] }); 
2

To solve this problem, you can do the following steps:

1- You used the data as input to the dialog and used it in the constructor to set the variables. (in .ts)

 constructor(public dialogRef: MatDialogRef<any>, @Inject(MAT_DIALOG_DATA) public data: any) { this.ip= data.ip; this.name= data.name; } 

2- We should create fake data, (in .spec.ts)

const data = { ip: '1.1.1.1', name: 'test' } 

3- We define provider as follows And we introduce data, (in .spec.ts)

 providers: [ {provide: MatDialogRef, useValue: {}}, {provide: MAT_DIALOG_DATA, useValue: data}, ] 

4- full code in .spec.ts

import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import {CustomDialogComponent} from './backup-list.component'; import {TranslateModule} from '@ngx-translate/core'; import {MAT_DIALOG_DATA, MatDialogModule, MatDialogRef} from '@angular/material'; import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing'; import {NO_ERRORS_SCHEMA} from '@angular/core'; const data = { ip: '1.1.1.1', name: 'test' }; describe('BackupListComponent', () => { let component: BackupListComponent; let fixture: ComponentFixture<BackupListComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [CustomDialogComponent], imports: [ TranslateModule.forRoot(), MatDialogModule, BrowserDynamicTestingModule ], providers: [ {provide: MatDialogRef, useValue: {}}, {provide: MAT_DIALOG_DATA, useValue: data}, ], schemas: [NO_ERRORS_SCHEMA] }) .compileComponents(); })); }); 

You can do this by the help of jasmine spy, as follow:

Step 1: Define the mock data

 const data = { title: 'title', message: 'message', summary: 'my summary' }; 

Step 2: Create jasmine spy for MatDialogRef (Write this inside beforeEach block)

const matDialogSpy = jasmine.createSpyObj('MatDialogRef', ['onNoClick', 'closeDialog']); 

onNoClick and closeDialog are methods inside MessagePopupComponnet

Step 3: Configure the TestBed as follow:

 providers: [ { provide: MatDialogRef, useValue: matDialogSpy }, { provide: MAT_DIALOG_DATA, useValue: data } ] 

For the ref, I've provided the full code below:

import { DebugElement } from "@angular/core"; import { async, ComponentFixture, TestBed } from "@angular/core/testing"; import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material"; import { MessagePopupComponent } from "./message-popup.component"; describe('MessagePopup', () => { let fixture: ComponentFixture<MessagePopupComponent>; let component: MessagePopupComponent; let el: DebugElement; let matDialogRef; const data = { title: 'title', message: 'message', summary: 'my summary' }; beforeEach(async(() => { const matDialogSpy = jasmine.createSpyObj('MatDialogRef', ['onNoClick', 'closeDialog']); TestBed.configureTestingModule({ declarations: [MessagePopupComponent], providers: [ { provide: MatDialogRef, useValue: matDialogSpy }, { provide: MAT_DIALOG_DATA, useValue: data } ] }).compileComponents() .then(() => { fixture = TestBed.createComponent(MessagePopupComponent); component = fixture.componentInstance; el = fixture.debugElement; matDialogRef = TestBed.get(MatDialogRef); }); })); fit('should create Message Popup component', () => { expect(component).toBeTruthy('Message popup not created') }); }); 
1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy