I'm trying to test the following get function using Jest. How can test / mock the Promise rejection in localForage.getItem, so that I can test the get catch block?
async get<T>(key: string): Promise<T | null> {
if (!key) {
return Promise.reject(new Error('There is no key to get!'));
}
try {
return await this.localForage.getItem(key);
} catch (err) {
throw new Error('The key (' key ") isn't accessible.");
}
}
I tried the following:
test('test get promise rejection', async () => {
const expectedError = new Error(
'The key (' 'fghgdfghfghfdh' ") isn't accessible."
);
jest.fn(localforage.getItem).mockRejectedValue(new Error());
expect(get('fghgdfghfghfdh')).rejects.toThrow(expectedError);
});
But I get the following error:
node:internal/process/promises:246
triggerUncaughtException(err, true /* fromPromise */);
^
[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Error: expect(received).rejects.toThrow()
Received promise resolved instead of rejected
Resolved to value: null".] {
code: 'ERR_UNHANDLED_REJECTION'
}
CodePudding user response:
Well... we remove the await keyword from this line
expect(await get('fghgdfghfghfdh')).rejects.toThrow(expectedError);
Because the error clearly states
received value must be a promise or a function returning a promise
Then the test fails because it expected to be rejected and insted is resolved with null value
So, either invoke get without a key
expect(get()).rejects.toThrow(expectedError);
Or make get function more defensive like this
async get<T>(key: string): Promise<T | null> {
if (!key) {
return Promise.reject(new Error('There is no key to get!'));
}
try {
const result = await this.localForage.getItem(key);
if (result) return result;
throw new Error('empty value');
} catch (err) {
throw new Error('The key (' key ") isn't accessible: ");
}
}
Which approach to use? I think both... anyhow I do hope you manage with your tests!
CodePudding user response:
I got it working, I had to replace localforage.getItem with jest.fn().mockRejectedValue:
test('test get promise rejection', async () => {
localforage.getItem = jest.fn().mockRejectedValue(new Error());
const expectedError = new Error(
'The key (' 'fghgdfghfghfdh' ") isn't accessible."
);
expect(handler.get('fghgdfghfghfdh')).rejects.toThrow(expectedError);
});
