$ quasar ext add @quasar/testing-unit-vitest
This package is in alpha phase. The public API may still change as we collect community feedback.
This App Extension (AE) manages Quasar and Vitest integration for you, both for JavaScript and TypeScript.
What is included:
vitest.config.ts
);installQuasarPlugin
function to help you setup and configure the test Quasar instance on a per-test-suite basis;test/vitest/__tests__
package.json
scripts;This AE is a lightweight add-on to “@vue/test-utils” package, which helps you test Vue components that rely on some Quasar features. Please check out “@vue/test-utils” official documentation to learn how to test Vue components.
Call this helper at the top of your test files. It will configure @vue/test-utils
to setup Quasar plugin every time mount
/shallowMount
is called.
It will also restore the original configuration after all tests completed.
Usage:
import { installQuasarPlugin } from '@quasar/quasar-app-extension-testing-unit-vitest';
import { mount } from '@vue/test-utils';
import ExampleComponent from '../ExampleComponent.vue';
/*
* You can provide a config object as param like such:
*
* ```ts
* installQuasarPlugin({ plugins: { Dialog } });
* ```
*/
installQuasarPlugin();
describe('ExampleComponent', () => {
it('should mount correctly', async () => {
mount(ExampleComponent, {});
});
});
Here’re some helpers which has not been included in the current AE version, but could be in future versions
https://github.com/posva/vue-router-mock
import { beforeEach } from 'vitest';
import {
createRouterMock,
injectRouterMock,
VueRouterMock,
RouterMockOptions,
} from 'vue-router-mock';
import { config } from '@vue/test-utils';
// https://github.com/posva/vue-router-mock
export function installRouter(options?: RouterMockOptions) {
beforeEach(() => {
const router = createRouterMock(options);
injectRouterMock(router);
});
config.plugins.VueWrapper.install(VueRouterMock);
}
// install-pinia.ts
import { config } from '@vue/test-utils';
import { cloneDeep } from 'lodash-es';
import { beforeAll, afterAll } from 'vitest';
import { createTestingPinia, TestingOptions } from '@pinia/testing';
import { Plugin } from 'vue';
export function installPinia(options?: Partial<TestingOptions>) {
const globalConfigBackup = cloneDeep(config.global);
beforeAll(() => {
config.global.plugins.unshift(
// This is needed because typescript will complain othwerwise
// Probably due to this being a monorepo as this same setup inside a test project did work correctly
createTestingPinia(options) as unknown as Plugin,
);
});
afterAll(() => {
config.global = globalConfigBackup;
});
}
// example-store.ts
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
counter: 0,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
actions: {
increment() {
this.counter++;
},
},
});
<!-- StoreComponent.vue -->
<template>
<div>
<q-btn @click="store.increment"> Increment </q-btn>
</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { useCounterStore } from './example-store';
const store = useCounterStore();
const counter = computed(() => store.counter);
</script>
// StoreComponent.test.ts
import { installQuasarPlugin } from '@quasar/quasar-app-extension-testing-unit-vitest';
import { mount } from '@vue/test-utils';
import { useCounterStore } from '../example-store';
import { describe, expect, it } from 'vitest';
import { installPinia } from './install-pinia.ts';
import StoreComponent from './StoreComponent.vue';
// Documentation: https://pinia.vuejs.org/cookbook/testing.html#unit-testing-a-store
installQuasarPlugin();
installPinia({ stubActions: false });
describe('store examples', () => {
it('should increment the counter', async () => {
const wrapper = mount(StoreComponent);
const store = useCounterStore();
expect(wrapper.text()).toContain(0);
const btn = wrapper.get('button');
expect(store.increment).not.toHaveBeenCalled();
await btn.trigger('click');
expect(store.increment).toHaveBeenCalled();
expect(wrapper.text()).toContain(1);
expect(store.counter).toBe(1);
});
});
cd test-project-vite
yarn sync:vitest # or "yarn sync:all", if it's the first time you run this command
yarn test:unit:ci # check if unit tests still work with the local version of the AE