I am currently working on unit test of a VueJS project, and I would like to create a my-component.spec.js test (with Jest) for a my-component.vue component that uses a myService service with the inject option. The test itself is not important. It's above all about learning how to properly mock a component that uses a service. After doing a lot of research, I tried to write my test that I think is on the right track, but I can't seem to get it to work completely. Here is the code with 3 console.log in the test file :
mock.js (file containing a simulated method of the myService service) :
export default function getAllInfos() {
return [
{"id": "myId", "name": "myName"}
];
}
my-component.spec.js :
import {mount} from "@vue/test-utils";
import MyComponent from "./my-component.vue";
import getAllInfos from "./mock";
describe("MyComponent", () => {
it("returns the correct value for getAllInfos() method", () => {
const wrapper = mount(MyComponent, {
"provide": {
myService() {
return {
"mock": {
"getAllInfos": getAllInfos()
}
};
},
},
data() {
return {
"infos": []
};
}
});
console.log("getAllInfos = ", wrapper.vm.$options.provide.myService().mock.getAllInfos);
const test = wrapper.vm.$options.provide.myService().mock.getAllInfos;
console.log("test = ", test);
wrapper.setData({"infos": test});
console.log("infos = ", wrapper.vm.$options.data().infos);
expect(wrapper.vm.$options.data().infos).toEqual([
{"id": "myId", "name": "myName"}
]);
});
});
I think I'm on the right track because when I run the npm run test:unit command, the first 2 console.log return the expected result :
getAllInfos = [{id: 'myId', name: 'myName'}]
test = [{id: 'myId', name: 'myName'}]
However, the 3rd console.log seems strange to me :
infos = []
This means the infos data is not assigned by the test constant, the content of which is correct.
Anyone have a solution for this problem ?
If you take a closer look at the docs (setData | Vue Test Utils), then you can see a small but significant difference to your code:
// your code:
/* ... */
it("returns the correct value for getAllInfos() method", () => {
/* ... */
wrapper.setData({"infos": test});
/* ... */
});
/* ... */
// code in docs:
/* ... */
test('setData demo', async () => {
/* ... */
await wrapper.setData({ foo: 'bar' })
/* ... */
})
Yes, the difference is that in the docs, the test is an async function and the setData is awaited. I think this is the source of your problem.
You could also try (but this is a bit of a workaround):
import { createLocalVue, mount } from "@vue/test-utils";
/* ... */
const localVue = createLocalVue()
/* ... */
wrapper.setData({"infos": test});
await localVue.nextTick()
/* ... */
Source for localVue here