我有一个名为
validateData()
的函数,它导入 json 文件 (data.json),并验证数据是否缺少任何字段。
我想编写多个 vitest
测试来测试该函数,并且我希望每个测试以不同的方式模拟 json 文件。
我尝试使用
vi.mock
进行模拟并确保提升默认导入,如下所示:
const mocks = vi.hoisted(() => {
return {
default: vi.fn(),
};
});
vi.mock('data/data.json', () => {
return {
default: mocks.default,
};
});
const obj1 = {
id: 1,
name: "obj1"
}
describe('validateData', () => {
test('with valid data', () => {
mocks.default.mockReturnValueOnce({ obj1 });
expect(validateData()).toStrictEqual([]);
});
test('with missing field', () => {
mocks.default.mockReturnValue({ obj1: { ...obj1, name: undefined } });
expect(validateData()).toStrictEqual(['Missing name for obj1']);
});
});
而数据 json 文件如下所示:
{
obj1: {
id: 1,
name: "obj1"
}
}
这仍然不起作用,
validateData
函数仍然使用实际的json而不是模拟。
我也遇到了这个问题,并设法通过使用
vi.doMock
,await import(...)
和vi.resetModules()
解决了它:
const obj1 = {
id: 1,
name: 'obj1'
}
describe('validateData', () => {
afterEach(() => vi.resetModules());
test('with valid data', async () => {
vi.doMock('data/data.json', () => ({ default: { obj1 } }));
const { validateData } = await import('./validator.js');
expect(validateData()).toStrictEqual([]);
});
test('with missing field', async() => {
vi.doMock('data/data.json', () => ({ default: { obj1: { ...obj1, name: undefined } } }));
const { validateData } = await import('./validator.js');
expect(validateData()).toStrictEqual(['Missing name for obj1']);
});
});
在您给定的代码中,
validateData
和JSON在开始时仅导入一次。
所以后面模拟的返回值就不再起作用了。
使用
doMock
和动态导入时,每个测试中都会导入模拟的 JSON。每次测试后不要忘记重置模块。