I have simple service that I need unit tested using jest:
the crux of the code is this:
domtoimage.toBlob(node, {filter: filter})
.then(function (blob) {
FileSaver.saveAs(blob, fileName);
});
I have wrote my unit test module as such:
import FileSaver from "file-saver";
import domtoimage from "dom-to-image";
jest.mock('dom-to-image', () => {
return {
toBlob: (arg)=>{
let promise = new Promise((resolve, reject) => {
resolve('myblob')
});
return promise;
}
}
});
jest.mock('file-saver', ()=>{
return {
saveAs: (blob, filename) =>{
return filename;
}
}
});
And in my test, I have the following spy set up
const spy = jest.spyOn(FileSaver, 'saveAs');
and calling my in-test function.
however, the expect statement: expect(spy).toBeCalled()
returns false:
expect(jest.fn()).toBeCalled()
However, in webstorm, when I debug the unit test, I can clearly see that my mocked function is being called (the breakpoint is reached inside function).
What am i missing?
I have simple service that I need unit tested using jest:
the crux of the code is this:
domtoimage.toBlob(node, {filter: filter})
.then(function (blob) {
FileSaver.saveAs(blob, fileName);
});
I have wrote my unit test module as such:
import FileSaver from "file-saver";
import domtoimage from "dom-to-image";
jest.mock('dom-to-image', () => {
return {
toBlob: (arg)=>{
let promise = new Promise((resolve, reject) => {
resolve('myblob')
});
return promise;
}
}
});
jest.mock('file-saver', ()=>{
return {
saveAs: (blob, filename) =>{
return filename;
}
}
});
And in my test, I have the following spy set up
const spy = jest.spyOn(FileSaver, 'saveAs');
and calling my in-test function.
however, the expect statement: expect(spy).toBeCalled()
returns false:
expect(jest.fn()).toBeCalled()
However, in webstorm, when I debug the unit test, I can clearly see that my mocked function is being called (the breakpoint is reached inside function).
What am i missing?
Share Improve this question asked Jun 12, 2018 at 5:12 NateNate 1,7504 gold badges25 silver badges41 bronze badges 1-
So I am able to figure out this is due to the promise inside
toBlob
...i need to wait for it to resolve (or force resolve) before checking spy – Nate Commented Jun 12, 2018 at 18:15
2 Answers
Reset to default 10Suggestion 1
Maybe spyOn and module mocks don't play well together. You could try using a jest.fn()
directly inside the module mock like so
jest.mock('file-saver', ()=>{
return {
saveAs: jest.fn((blob, filename) => {
return filename;
})
}
});
and then
expect(FileSaver.saveAs).toBeCalled()
Remember to call jest.clearAllMocks()
or similar between tests.
Suggestion 2
I've had issues with jest.mock working in unexpected ways with the jest module cache, especially when working with singleton imports. Maybe you have this issue. if file-saver
and dom-to-image
don't have any state initialized or side-effects on import time you should be able to swap jest.mock
out for overrides of the functions you need to mock.
beforeEach(() => {
FileSaver.saveAs = jest.fn(...);
domtoimage.toBlob = jest.fn(...);
})
So for those of you wondering something similar...my issue (as I suspected) was the promise in domtoimage.toBlob(node, {filter: filter}).then()
essentially, the promise was resolving after my expect was called.
in order to solve it, I placed my expect
behind a setTimeout, thus forcing it to fire after the promise is resolved.
DownloadImage('x', 'name');
//small timeout to resolve the promise inside downldimage function
setTimeout(()=>{
expect(FileSaver.saveAs).toHaveBeenCalledWith('myblob', fileName);
done();
}, 100);