Reputation: 298
I wanted to test if the the object returned by the service calls a specific method.
The component method is async
since the service will return a Promise
.
Here's the component code.
// component
export class FilterComponent {
constructor(
private modalController: ModalController,
) { }
async onFilterClicked() {
const modal = await this.modalController.create({
component: FilterModalPage,
});
modal.onDidDismiss().then(res => {
if (res.data) {
// do something
}
});
await modal.present();
}
}
and this is my test
describe('FilterComponent', () => {
let fixture: ComponentFixture<FilterComponent>;
let component: FilterComponent;
let modalControllerSpy;
let modalSpy;
beforeEach(async () => {
modalControllerSpy = jasmine.createSpyObj('modalController', ['create']);
modalSpy = jasmine.createSpyObj('modal', ['present']);
TestBed.configureTestingModule({
declarations: [FilterComponent],
providers: [
{ provide: ModalController, useValue: modalControllerSpy },
]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(FilterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
describe('onFilterClicked', () => {
it('should `present` the modal', () => {
modalControllerSpy.create.and.returnValue(modalSpy);
component.onFilterClicked();
fixture.detectChanges();
expect(modalControllerSpy.create).toHaveBeenCalled(); // success
expect(modalSpy.present).toHaveBeenCalled(); // fail :( how to test `present` is called????
});
});
});
I created spy object on the first beforeEach
callback.
modalControllerSpy = jasmine.createSpyObj('modalController', ['create']);
modalSpy = jasmine.createSpyObj('modal', ['present']);
I wanted to test if my modalSpy
calls present
function.
Perhaps I did something wrong here.
Upvotes: 2
Views: 3232
Reputation: 14958
I would refactor the test suite as follow:
// ...
// create a valid response for ModalController#create according to the logic in controller where it is used
const modalObj = {
onDidDismiss: () => Promise.resolve({ res: { data: 'test-value1' } })
};
// ...
beforeEach(async () => {
// create a spy object with the methods you want to spy on
modalControllerSpy = jasmine.createSpyObj('ModalController', ['create', 'present']);
// mock the returned value from the service
modalControllerSpy.create.and.returnValue(modalObj);
modalControllerSpy.present.and.returnValue(Promise.resolve('test-value2'));
TestBed.configureTestingModule({
declarations: [FilterComponent],
providers: [
{ provide: ModalController, useValue: modalControllerSpy },
]
}).compileComponents();
});
// ...
it('should `present` the modal', () => {
component.onFilterClicked();
fixture.detectChanges(); // maybe you don't need this, check if the test passes without it
expect(modalControllerSpy.create).toHaveBeenCalled();
expect(modalControllerSpy.present).toHaveBeenCalled();
// you could add some additional checks here regarding to the returned values
// in the promises since they were mocked: 'test-value1' and 'test-value2'
});
});
// ...
Upvotes: 1
Reputation: 6060
The return value from create()
needs to be a promise. Try the following:
it('should `present` the modal', () => {
modalControllerSpy.create.and.returnValue(Promise.resolve(modalSpy));
component.onFilterClicked();
fixture.detectChanges();
expect(modalControllerSpy.create).toHaveBeenCalled(); // success
expect(modalSpy.present).toHaveBeenCalled(); // should pass now
});
See docs here
Upvotes: 0