I am opening my mat-dialog with the following function:
accept() {
let dialogRef = this.dialog.open(AcceptDialogComponent, {
data: {
hasAccepted: false
}
})
dialogRef.afterClosed().subscribe(result => {
console.log(result);
if (result.hasAccepted === true) {
this.leadService.acceptLead(this.holdingAccountId, this.lead.id)
.pipe(
takeUntil(this.onDestroy$)
)
.subscribe(acceptLeadRes => {
console.log(acceptLeadRes);
this.leadService.updateLeadAction('accept');
},
(err: HttpErrorResponse) => {
console.log(err);
this.router.navigate(['/error']);
});
}
});
}
I am attempting to write a test for this function that simply fires the afterClosed() so that I can check if my service method that makes a backend call is called.
component.spec.ts (beforeEach Testbed creation)
beforeEach(async (() => {
TestBed.configureTestingModule({
declarations: [LeadCardComponent, AcceptDialogComponent],
imports: [
requiredTestModules,
JwtModule.forRoot({
config: {
tokenGetter: () => {
return '';
}
}
})
],
providers: [
ApplicationInsightsService,
JwtHelperService,
// { provide: LeadsService, useValue: leadServiceSpy }
],
}),
TestBed.overrideModule(BrowserDynamicTestingModule, {
set: {
entryComponents: [AcceptDialogComponent]
}
});
TestBed.compileComponents();
}));
component.spec.ts (test)
it('Return from AcceptLeadDialog with hasAccepted equals true should call acceptLead endpoint', () => {
let matDiaglogref = dialog.open(AcceptDialogComponent, {
data: {
hasAccepted: false
}
});
spyOn(matDiaglogref, 'afterClosed').and.callThrough().and.returnValue({
hasAccepted: true
});
spyOn(leadService, 'acceptLead').and.callThrough();
component.acceptLead();
fixture.detectChanges();
matDiaglogref.close();
fixture.detectChanges();
expect(leadService.acceptLead).toHaveBeenCalled();
});
The test currently fails with a "Expected spy acceptLead to have been called." I am failing on understanding how to test the function and execute some sort of mock MatDialogRef so that I can check if the conditions of my test pass.
Any help/suggestions would be much appreciated
Update Working Test implemented from Accepted Answer
it('Return from AcceptLeadDialog with hasAccepted equals true should call acceptLead endpoint', () => {
spyOn(component.dialog, 'open')
.and
.returnValue({
afterClosed: () => of({
hasAccepted: true
})
});
spyOn(leadService, 'acceptLead').and.callThrough();
component.acceptLead();
expect(component.dialog).toBeDefined();
expect(leadService.acceptLead).toHaveBeenCalled();
});
You can test Angular Material Dialog's afterClosed method this way: 1 import { of } from 'rxjs'; 2 spy on the dialog and return an observable for the afterClosed () method More ...
Of course, if you have a test that needs to interact with another component, such as through a view child, you need to have a mock of the component, if you don’t want to create an integration test. What you will often see in Angular libraries, eg. Angular Routing library, is that it provides a testing module for easier mocking in unit tests.
What you will often see in Angular libraries, eg. Angular Routing library, is that it provides a testing module for easier mocking in unit tests. I recommend that you do the same with components you want to create mocks for, by creating a *component-name*.component.mock.ts beside the component file, so you can easily get a mock of the component.
Angular Routing library, is that it provides a testing module for easier mocking in unit tests. I recommend that you do the same with components you want to create mocks for, by creating a *component-name*.component.mock.ts beside the component file, so you can easily get a mock of the component.
I solved this problem as the first post by @Adithya Sreyaj but added the next change:
spyOn(component.dialog, 'open')
.and
.returnValue({
afterClosed: () => of(true)
} as MatDialogRef<typeof component>);
You can test Angular Material Dialog's afterClosed method this way:
import { of } from 'rxjs';
afterClosed()
method spyOn(component.dialog, 'open')
.and
.returnValue({afterClosed: () => of(true)});
Basically, the afterClosed()
of the dialogRef is expecting an Observable. So we spy on the component's dialog open method and return an Observable for the afterClosed()
method by using the of
operator from rxjs
.
You can then replace the of(true)
from the returnValue
with your own data what you are sending in the afterClosed()
of the dialog in the main component.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With