我使用 vue-test-utils
@1.1.3 和 jest
@26 来测试我的组件。
组件从父级获取 provide
数据,并监视它的变化。
父组件注入一个计算值。我想检查观察者(及其调用的功能)是否按预期工作。
我想知道如何更改我在测试中提供的模拟数据?
// ParentComponent.vue, using the @vue/composition-api plugin + syntax
setup() {
let chosenItems = reactive({ items: [] })
function UpdateItems(items) {
chosenItems.items = [...items]
}
provide(
"userItems",
computed(() => chosenItems.items)
)
return { UpdateItems }
}
// The component I want to test, using options-api syntax
export default {
inject: ["userItems"],
watch: {
"userItems.value": function (items) {
// Do Things...
},
},
}
// The test code for the component
const wrapper = mount(ComponentToTest, {
localVue,
router,
provide: {
userItems() {
return ["mockedItems"]
},
},
})
// And now, after mounting, I want to change the data was provided to test the watcher
答案 0 :(得分:0)
除了调用 wrapper.setData({ userItems: ["mockedNewItems"] })
之外,我找不到其他方法。
它会工作并触发观察者,但就好像您正在改变提供的数据一样,这并不理想。
答案 1 :(得分:0)
或者,需要做更多工作但不会改变提供的数据的方法是从 ParentComponent.vue
中提取这部分:
setup() {
let chosenItems = reactive({ items: [] })
function UpdateItems(items) {
chosenItems.items = [...items]
}
provide(
"userItems",
computed(() => chosenItems.items)
)
return { UpdateItems }
}
到一个单独的函数,它提供它(在一个单独的文件中):
export default function provideChosenItems() {
let chosenItems = reactive({ items: [] });
function UpdateItems(items) {
chosenItems.items = [...items];
}
provide(
"userItems",
computed(() => chosenItems.items)
);
return { UpdateItems };
}
因此,在您的测试中,您可以挂载父组件,模拟提供程序函数的实现,然后更改提供的数据:
import ParentComponent from "ParentComponent.vue";
import provideChosenItems from "provideChosenItems";
import VueCompositionApi, { provide, ref } from "@vue/composition-api";
import { createLocalVue, mount } from "@vue/test-utils";
const localVue = createLocalVue();
localVue.use(VueCompositionApi);
jest.mock("provideChosenItems");
describe("test", () => {
it("test", () => {
const mockedItems = ["mockedItems1"];
provideChosenItems.mockImplementation(() => {
provide("userItems", ref(mockedItems));
return { UpdateItems: () => {} };
});
const wrapper = mount(ParentComponent, {
localVue
});
mockedItems.push("mockedItems2");
// Data is changed, so you can test what happens afterwards,
// you could do something like
// wrapper.findComponent(ComponentUnderTest) and assert on stuff
});
});
答案 2 :(得分:0)
不确定它是否适用于 vue2 组合 API,但它应该适用于具有类似语法的 vue3。
解决方案的重点是“提供”inject
期望接收的东西,这是一个反应引用。否则对组件中的“观察”没有任何反应。
it('test provide watch effect', () => {
const chosenItems = reactive({ items: ["mockItems"] });
const items = computed(() => chosenItems.items)
const wrapper = mount(ComponentToTest, {
localVue,
router,
provide: {
userItems() {
return items
},
},
})
// doing stuff and await for mounting
chosenItems.items = ["mockItems", "mockItems2"]
// await flushPromise
should('watch the change of chosenItems')
})
由于新的反应式系统应该在没有 Vue 的情况下继续存在,您可以直接在 vue 项目之外导入 ref
、reactive
、computed
,在您的情况下,是测试文件。< /p>