I need to test a function (example()
), which uses another one (validateDataset
). As I only want to test the example()
function I mock the validateDataset()
.
Of course each test needs a different result of the mocked function. But how do I set different promise results for the mocked function? In my attempt shown below the mocked function always return the same value.
So in this example I cannot test for the thrown error.
functions.js
import { validateDataset } from './helper/validation'
export async function example (id) {
const { docElement } = await validateDataset(id)
if (!docElement) throw Error('Missing content')
return docElement
}
functions.test.js
import { example } from './functions'
jest.mock('./helper/validation', () => ({
validateDataset: jest.fn(() => Promise.resolve({
docMain: {},
docElement: {
data: 'result'
}
}))
}))
describe('example()', () => {
test('should return object', async () => {
const result = await example('123')
expect(result.data).toBe('result')
})
test('should throw error', async () => {
const result = await example('123')
// How to get different result (`null`) in this test
// How to test for the thrown error?
})
})
What's great about Jest mocking, is that you can mock-out the whole module, and by requiring its default or named exports, you still get a mock, which you can implement and reimplement however and wherever you like.
I've posted a sample implementation of the test that expects validateDataset
call to fail. I also left some comments for brevity.
import { example } from './example';
import { validateDataset } from './helper/validation';
// Declare export of './helper/validation' as a Mock Function.
// It marks all named exports inside as Mock Functions too.
jest.mock('./helper/validation');
test('example() should return object', async () => {
// Because `validateDataset` is already mocked, we can provide
// an implementation. For this test we'd like it to be original one.
validateDataset.mockImplementation(() => {
// `jest.requireActual` calls unmocked module
return jest.requireActual('./helper/validation').validateDataset();
});
const result = await example('123');
expect(result.data).toBe('result');
});
test('example() should throw error', async () => {
// Worth to make sure our async assertions are actually made
expect.assertions(1);
// We can adjust the implementation of `validateDataset` however we like,
// because it's a Mock Function. So we return a null `docElement`
validateDataset.mockImplementation(() => ({ docElement: null }));
try {
await example('123');
} catch (error) {
expect(error.message).toEqual('Missing content');
}
});
Hope that clears things out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With