我需要测试一个函数(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'); } });
希望能把事情搞清楚.