'Jest does not detect my mock call in promise .catch block
Jest does not seem to be detecting my mock calls in the catch block. Yet, if don't mock the method handleError, I'll receive an error. I have tried multiple ways of doing the returned rejected promise but no luck so far.
I've tried callbacks, Promise.reject, Promise((res, rej) => {})
Code being tested:
module.exports = class PresetDropdown {
constructor (Api, objectId, titleSort) {
this.Api = Api;
this.objectId; = objectId;
this.presets = [];
}
handleError (err) {
console.log(err)
// more functionality
}
get () {
this.Api.getMany(this.objectId)
.then((data) => {
this.handleEmpty(data);
this.isError = false;
})
.catch((err) => {
this.isError = true;
this.handleError(err);
});
}
};
Test (Jest):
test('Expect call from handleError after reject promise', async () => {
// assemble
// return the class
const Module = getModule();
const mockRejectedPromise = jest.fn(() => {
return Promise.reject(Error(mockError));
});
mockApi.getMany = mockRejectedPromise;
const module = new Module(mockApi, '1', null);
const mockHandleError = jest.fn(() => {});
PresetTemplate.handleError = mockHandleError;
// act
await PresetTemplate.get(mockScope);
// assert
expect(mockHandleError).toHaveBeenCalledTimes(1); // DOES NOT DETECT CALL
// Test CASE FAILS HERE ^
});
Solution 1:[1]
Since PresetDropdown class accept an Api object, you can create a mocked Api object and pass it to the class. Then mock resolved/rejected value for Api.getMany() method, so that you can test different code branches.
E.g.
presetDropdown.js:
module.exports = class PresetDropdown {
constructor(Api, objectId, titleSort) {
this.Api = Api;
this.objectId = objectId;
this.presets = [];
}
handleError(err) {
console.log(err);
}
handleEmpty(data) {
console.log(data);
}
get() {
return this.Api.getMany(this.objectId)
.then((data) => {
this.handleEmpty(data);
this.isError = false;
})
.catch((err) => {
this.isError = true;
this.handleError(err);
});
}
};
presetDropdown.test.js:
const PresetDropdown = require('./presetDropdown');
describe('71164955', () => {
test('should handle data', async () => {
const mockApi = {
getMany: jest.fn().mockResolvedValueOnce('fake data'),
};
const instance = new PresetDropdown(mockApi, '1');
await instance.get();
expect(instance.isError).toBeFalsy();
});
test('should handle error', async () => {
const mockError = new Error('fake error');
const mockApi = {
getMany: jest.fn().mockRejectedValueOnce(mockError),
};
const instance = new PresetDropdown(mockApi, '1');
await instance.get();
expect(instance.isError).toBeTruthy();
});
});
Test result:
PASS stackoverflow/71164955/presetDropdown.test.js
71164955
? should handle data (14 ms)
? should handle error (3 ms)
console.log
fake data
at PresetDropdown.handleEmpty (stackoverflow/71164955/presetDropdown.js:11:13)
console.log
Error: fake error
at Object.<anonymous> (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/stackoverflow/71164955/presetDropdown.test.js:12:23)
at Object.asyncJestTest (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:106:37)
at /Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:45:12
at new Promise (<anonymous>)
at mapper (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:28:19)
at /Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:75:41
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at PresetDropdown.handleError (stackoverflow/71164955/presetDropdown.js:8:13)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 1.311 s
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | slideshowp2 |
