如何在每个测试中以不同方式模拟用户模块?
How to mock a user module differently in each test?
我对我的 Vue 组件进行了以下单元测试:
import { shallowMount } from '@vue/test-utils';
import OrganizationChildren from './OrganizationChildren.vue';
describe('OrganizationChildren', () => {
beforeEach(() => {
jest.resetModules();
});
it('passes', () => {
jest.doMock('@/adonis-api', () => {
return {
organization: {
family(id) {
return {
descendants: [],
};
},
},
};
});
const wrapper = shallowMount(OrganizationChildren, {
propsData: {
org: {
id: 1,
},
},
});
});
});
而在 Vue 组件中,它确实 import { organization } from '@/adonis-api';
。我暂时只是 console.logging 导入的 organization
对象,以确保它是正确的。但我可以看到它没有使用我指定的模拟版本。我究竟做错了什么?我的目标是在每个 it()
块中以不同方式模拟 family
方法,以测试如果 descendants
为空、包含 5 个项目、100 个项目等时会发生什么
已解决!事实证明,我有几个问题:
- 没有正确地模拟
@/adonis-api
。我应该提到它只模拟顶层的东西,所以我不得不在 jest.mock
(见下文)中使用工厂函数。
- 我需要一个
await flushPromises()
来允许模板在其 created()
方法评估我的模拟函数并将结果存储在 this.children
后 re-render。
完整测试:
import { shallowMount, config } from '@vue/test-utils';
import flushPromises from 'flush-promises';
import OrganizationChildren from './OrganizationChildren.vue';
import { organization } from '@/adonis-api';
jest.mock('@/adonis-api', () => ({
organization: {
family: jest.fn(),
},
}));
describe('OrganizationChildren', () => {
config.stubs = {
'el-tag': true,
};
it('shows nothing when there are no children', async () => {
organization.family.mockResolvedValueOnce({
descendants: [],
});
const wrapper = shallowMount(OrganizationChildren, {
propsData: {
org: {
id: 1,
},
},
});
await flushPromises();
const h4 = wrapper.find('h4');
expect(h4.exists()).toBe(false);
});
it('shows children when provided', async () => {
organization.family.mockResolvedValueOnce({
descendants: [{ name: 'One' }, { name: 'Two' }],
});
const wrapper = shallowMount(OrganizationChildren, {
propsData: {
org: {
id: 1,
},
},
});
await flushPromises();
const h4 = wrapper.find('h4');
const list = wrapper.findAll('el-tag-stub');
expect(h4.exists()).toBe(true);
expect(list.length).toBe(2);
expect(list.at(0).text()).toBe('One');
expect(list.at(1).text()).toBe('Two');
});
});
我对我的 Vue 组件进行了以下单元测试:
import { shallowMount } from '@vue/test-utils';
import OrganizationChildren from './OrganizationChildren.vue';
describe('OrganizationChildren', () => {
beforeEach(() => {
jest.resetModules();
});
it('passes', () => {
jest.doMock('@/adonis-api', () => {
return {
organization: {
family(id) {
return {
descendants: [],
};
},
},
};
});
const wrapper = shallowMount(OrganizationChildren, {
propsData: {
org: {
id: 1,
},
},
});
});
});
而在 Vue 组件中,它确实 import { organization } from '@/adonis-api';
。我暂时只是 console.logging 导入的 organization
对象,以确保它是正确的。但我可以看到它没有使用我指定的模拟版本。我究竟做错了什么?我的目标是在每个 it()
块中以不同方式模拟 family
方法,以测试如果 descendants
为空、包含 5 个项目、100 个项目等时会发生什么
已解决!事实证明,我有几个问题:
- 没有正确地模拟
@/adonis-api
。我应该提到它只模拟顶层的东西,所以我不得不在jest.mock
(见下文)中使用工厂函数。 - 我需要一个
await flushPromises()
来允许模板在其created()
方法评估我的模拟函数并将结果存储在this.children
后 re-render。
完整测试:
import { shallowMount, config } from '@vue/test-utils';
import flushPromises from 'flush-promises';
import OrganizationChildren from './OrganizationChildren.vue';
import { organization } from '@/adonis-api';
jest.mock('@/adonis-api', () => ({
organization: {
family: jest.fn(),
},
}));
describe('OrganizationChildren', () => {
config.stubs = {
'el-tag': true,
};
it('shows nothing when there are no children', async () => {
organization.family.mockResolvedValueOnce({
descendants: [],
});
const wrapper = shallowMount(OrganizationChildren, {
propsData: {
org: {
id: 1,
},
},
});
await flushPromises();
const h4 = wrapper.find('h4');
expect(h4.exists()).toBe(false);
});
it('shows children when provided', async () => {
organization.family.mockResolvedValueOnce({
descendants: [{ name: 'One' }, { name: 'Two' }],
});
const wrapper = shallowMount(OrganizationChildren, {
propsData: {
org: {
id: 1,
},
},
});
await flushPromises();
const h4 = wrapper.find('h4');
const list = wrapper.findAll('el-tag-stub');
expect(h4.exists()).toBe(true);
expect(list.length).toBe(2);
expect(list.at(0).text()).toBe('One');
expect(list.at(1).text()).toBe('Two');
});
});