'Injecting data into a vue3 vitest
I've written a test for vue3 for one of my components:
import { describe} from 'vitest';
import { shallowMount } from '@vue/test-utils';
import ProgressBar from '@/components/ProgressBar.vue';
const messages = {
"en-US" : {
strings: {
a: "A",
b: "B",
c: "C"
}
},
"fr-CA": {
strings: {
a: "AA",
b: "BB",
c: "CC"
}
}
};
const locale = "en-US";
try {
describe("ProgressBar.vue", () => {
function stepClick() {
console.log("step click");
}
const stepData = {
steps: [
{ index: 1, completed: false, clickActive: false },
{ index: 2, completed: false, clickActive: false },
{ index: 3, completed: false, clickActive: false }
],
currentIndex: 1
};
const component = shallowMount(ProgressBar, {
props: {
stepDataSource: "stepData",
onClick: stepClick,
locPage: "strings",
locKeys:['a', 'b', 'c' ]
},
provide: {
stepData() { return stepData }
},
mocks: {
'$t': (key) => {
const params = key.split('.');
return messages[locale][params[0]][params[1]];
}
}
});
});
} catch (e) {
console.log(e);
}
The component injects the specified data in properties:
stepDataSource: "stepData"
It is loaded by a method in the component:
async getStepData() {
console.log('getStepData');
const stepData = inject(this.stepDataSource) as StepData;
this.data.stepData = stepData;
const instance = getCurrentInstance();
instance?.proxy?.$forceUpdate();
},
Which works in normal running but it doesn't seem to get passed by the test. AFAIK, my mock of locale is working.
So what am I doing wrong to inject the step data for the test? I understand that I don't actually have any tests yet, but I need to get it to mount first.
Solution 1:[1]
This is a working test. It mocks $t successfully. I gave up trying to write them in typescript, this is a javascript file in the src/tests folder. If you need additional info about how to setup the rest of the project, go ahead and ask here.
import { describe, test, it, expect } from 'vitest';
import { ref } from 'vue';
import ProgressBar from '@/components/ProgressBar.vue';
import { mount } from "@vue/test-utils";
describe("ProgressBar.vue", () => {
const messages = {
"en-US" : {
strings: {
a: "A",
b: "B",
c: "C"
}
},
"fr-CA": {
strings: {
a: "AA",
b: "BB",
c: "CC"
}
}
};
const locale = "en-US";
const clickedItems = {1: false, 2: false, 3: false};
function stepClick(index) {
console.log("index:" + index);
clickedItems[index] = true;
}
const stepData = ref({
steps: [
{ index: 1, completed: true, clickActive: true },
{ index: 2, completed: false, clickActive: true },
{ index: 3, completed: false, clickActive: false }
],
currentIndex: 2
});
test ("Arrange ProgressBar", async () => {
const component = mount(ProgressBar, {
props: {
stepData: stepData,
onClick: stepClick,
locPage: "strings",
locKeys:['a', 'b', 'c']
},
global: {
mocks: {
$t: (msg) => {
const params = msg.split('.');
return messages[locale][params[0]][params[1]];
}
}
}
});
let multipleActive = false;
const progItems = component.findAll('.prog-item');
let selectedIndex = -1;
progItems.forEach((item, index) => {
if (item.element.className.indexOf("current") > -1) {
if (selectedIndex < 0) {
selectedIndex = index + 1; //indexes are 1 based for this control
} else {
multipleActive = true;
}
}
item.find("span.prog-item-outer").trigger('click');
});
expect(!multipleActive, "Only one Progbar item is selected").toBeTruthy();
expect(selectedIndex === 2, "Correct Progbar Item selected,").toBeTruthy();
expect(clickedItems[1] && !clickedItems[2] && !clickedItems[3], "Correct progBar indexes are return and correct items are click-active").toBeTruthy();
});
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | GeeWhizBang |
