我需要测试一个函数(example()),它使用另一个函数(validateDataset).因为我只想测试example()函数,所以我模拟了validateDataset().
当然,每个测试都需要模拟函数的不同结果.但是如何为模拟函数设置不同的promise结果?在我下面显示的尝试中,模拟函数始终返回相同的值.
所以在这个例子中,我无法测试抛出的错误.
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?
- })
- })
解决方法
Jest模拟的好处在于,你可以模拟整个模块,并且通过要求它的默认或命名导出,你仍然可以得到一个模拟,你可以实现和重新实现,无论你喜欢什么.
我发布了一个测试的示例实现,期望validateDataset调用失败.为简洁起见,我还留了一些评论.
- 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');
- }
- });
希望能把事情搞清楚.