I'm using Vue 3's Composition API like so:
store.ts
import { ref, Ref } from 'vue';
import { defineStore } from 'pinia';
export const useStore = defineStore('store', () => {
const isLoading: Ref<boolean> = ref(true);
function init() {
isLoading.value = true;
setTimeout(() => (isLoading.value = false), 3000);
}
return {
init,
isLoading,
};
});
Component.vue
<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import { storeToRefs } from 'pinia';
import { useStore } from './store';
const { t } = useI18n();
const store = useStore();
const { isLoading } = storeToRefs(store);
</script>
<template>
<wb-button @click="store.init()">{{ t('init') }}</wb-button>
<p>Loading: {{ isLoading ? 'Yes' : 'No' }}</p>
</template>
That all works fine and dandy but when I try to test stuff it gets messy. So far I have mocked vue-i18n globally like this:
testSetup.ts
import { vi } from 'vitest';
vi.mock('vue-i18n', () => ({
useI18n: () => ({
t: (key: string) => key,
d: (key: string) => key,
}),
}));
However, that works only until I try mocking the store simultaneously like this:
Component.test.ts
import { it, expect, vi } from 'vitest';
import { mount} from '@vue/test-utils';
import { createTestingPinia } from '@pinia/testing';
import Component from './Component.vue';
const options = {
global: {
plugins: [
createTestingPinia({
createSpy: vi.fn(),
initialState: {
items: [],
},
}),
],
},
};
it('works', () => {
const wrapper = mount(Component, options);
expect(wrapper.findComponent(Component)).toBeTruthy();
});
As soon as I add the change to the plugin configuration to enable the Pinia mock, the vue-i18n mock stops working and throws the old familiar TypeError: $setup.t is not a function
. I also tried to use config.global.mocks
and config.global.plugins
to mock vue-i18n but all of these solutions stop working as soon as I add Pinia mocking to the tests. I think the reason is that the config.global
object is somehow reset by @pinia/testing
but I don't know how to prevent this behavior.
package.json
"@pinia/testing": "0.0.16",
"@types/jsdom": "21.1.1",
"@types/node": "18.16.2",
"@vue/test-utils": "2.3.2",
"jsdom": "21.1.1"
"typescript": "~4.8.4",
"vite": "4.3.3",
"vitest": "0.30.1",
The issue is that the createSpy
property expects a function but a call was supplied. Change vi.fn()
to vi.fn
and everything works as expected.
createTestingPinia({
createSpy: vi.fn, <--
...
})
Source: https://pinia.vuejs.org/cookbook/testing.html#specifying-the-createspy-function