How to do jasmine unit test case for angular 6 bootstrap 4 modal
13,670
This is how I've tested it in the past...
Assuming the component TS file looks like this:
export class MyComponent {
closeResult: string;
constructor(private _modalService: NgbModal) {}
public openModal(content): void {
this._modalService.open(content, { size: 'lg' }).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
private getDismissReason(reason: any): string {
return `with: ${reason}`;
}
}
You can use the following test class which will test these scenarios:
this._modalService.open
is called with the correct parameters- When the modal is closed,
closeResult
is updated correctly - When the modal is dimissed,
closeResult
is updated correctly
The test class looks like this:
import { TestBed, async, ComponentFixture, tick, fakeAsync } from '@angular/core/testing';
import { NgbModal, NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { MyComponent } from './my.component';
// Mock class for NgbModalRef
export class MockNgbModalRef {
result: Promise<any> = new Promise((resolve, reject) => resolve('x'));
}
describe('MyComponent', () => {
let fixtureUnderTest: ComponentFixture<MyComponent>;
let componentUnderTest: MyComponent;
let modalService: NgbModal;
let mockModalRef: MockNgbModalRef = new MockNgbModalRef();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
MyComponent
],
imports: [
NgbModule.forRoot()
]
}).compileComponents();
fixtureUnderTest = TestBed.createComponent(MyComponent);
componentUnderTest = fixtureUnderTest.componentInstance;
modalService = TestBed.get(NgbModal);
}));
it('should open modal', () => {
spyOn(modalService, 'open').and.returnValue(mockModalRef);
componentUnderTest.openModal('<xxxx>');
expect(modalService.open).toHaveBeenCalledWith('<xxxx>', { size: 'lg' });
});
// Needs to be async as modal result returned in a promise
it('should update closeResult when modal closed', fakeAsync(() => {
spyOn(modalService, 'open').and.returnValue(mockModalRef);
componentUnderTest.openModal('<xxxx>');
tick();
expect(componentUnderTest.closeResult).toBe('Closed with: x');
}));
// Needs to be async as modal result returned in a promise
it('should update closeResult when modal dismissed', fakeAsync(() => {
spyOn(modalService, 'open').and.returnValue(mockModalRef);
// Override the result returned from the modal so we can test what happens when the modal is dismissed
mockModalRef.result = new Promise((resolve, reject) => reject('y'));
componentUnderTest.openModal('<xxxx>');
tick();
expect(componentUnderTest.closeResult).toBe('Dismissed with: y');
}));
});
Author by
Reshma
UI dev with a little bit of Angular, Typescript, Javascript, HTML, CSS and Node :)
Updated on June 26, 2022Comments
-
Reshma about 2 years
html
<ng-template #content let-modal> <h1>Modal content inside this ng-template #content </h1> </ng-template>
Button to open model
<button (click)="open(content)" > Open modal </button>
In ts file
import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap'; constructor( public modalService: NgbModal) { } open(content) { this.modalService.open(content, { ariaLabelledBy: 'modal-basic-title', size: 'lg' }).result.then((result) => { this.closeResult = `Closed with: ${result}`; }, (reason) => { this.closeResult = `Dismissed ${this.getDismissReason(reason)}`; }); }
How to do a jasmine test case for this open function.
-
Reshma over 5 yearsHi @ian-a i worked for me , the second test case is failing other 2 are working. but some times an error is throwing "Uncaught TypeError: Cannot read property 'code' of undefined thrown" . If any idea about this please help
-
Ian A over 5 yearsDo you have a
code
variable anywhere in your component TS file? -
Reshma over 5 years:) thanks for the clue. yes there was & i checked for undefined it worked .
-
Bmoe about 4 years@IanA how would I do this same test, except instead of calling openModal method on componentUnderTest, I would actually query the DOM for a button that when clicked opens the modal?
-
Ian A almost 4 years@Bmoe assuming you have a button with the ID
open-modal-button
that calls the a function which opens the modal, you should be able to sayfixtureUnderTest.debugElement.query(By.css('#open-modal-button')).nativeElement.click();
to trigger opening the modal by clicking the button. The variablefixtureUnderTest
would be an instance ofComponentFixture<MyComponent>
which can be instantiated in thebeforeEach
of the test class setup -
Adam Hughes over 2 yearsI'm not a big fan of these spys. Why can't we do a test where we actually confirm the subsequent modal window opens correctly? IE "user clicks button, wait a bit, modal should exist in DOM". In my tests the modal HTML element never opens