I am trying to write a test, using vitest , to assert a computed property in a vue3 component that is defined with script setup .
Consider a simple component:
// simple.vue
<script lang="ts" setup>
import { computed } from 'vue';
const hello = computed((): string => {
return 'Hello';
});
</script>
<template>
{{ hello }}
</template>
My test is like this:
describe('Hello', () => {
it('should compute hello', () => {
const wrapper = mount(Hello);
expect(wrapper.vm.hello).toBe('Hello');
});
});
This test actually works as expected when run using vitest
, so functionally things seem to be working well.
However, VSCode cannot see the computed properties on the vm
object:
It is able to see normal properties (eg, those defined with the defineProps
macro). Is this just a problem with VSCode-specific tooling, or is there another way I should be going about testing computed properties in vue3 components?
If this is the preferred method, is there a way to pull in the types of the computed properties (similar to how the types of the defined props seem to be pulled in)?
I have tried the technique described in this Vue Testing Handbook , but this doesn't work at all and I assume it must be specific to vue2.
From Vue docs :
Components using
<script setup>
are closed by default - ie the public instance of the component, which is retrieved via template refs or$parent
chains, will not expose any of the bindings declared inside<script setup>
.
This also affects the type of the wrapper.vm
in Vue Test Utils, such that it only includes public or exposed props of the <script setup>
component.
In your case, use the defineExpose()
compiler macro to expose hello
:
<script lang="ts" setup>
import { computed } from 'vue';
const hello = computed((): string => {
return 'Hello';
});
👇
defineExpose({ hello });
</script>
I assume that the mount
you are using is from @vue/test-utils
. You can type the wrapper like this to have typescript autocompletion and don't have errors:
import {mount, VueWrapper} from "@vue/test-utils";
import HelloWorld from "@/components/HelloWorld.vue"
import { ComponentPublicInstance } from "vue";
type MyComponentProps = any
type MyComponentVariables = {
hello: string
}
type MyComponentWrapperType = VueWrapper<ComponentPublicInstance<MyComponentProps, MyComponentVariables>>
describe('Hello', () => {
it('should compute hello', () => {
const wrapper: MyComponentWrapperType = mount(HelloWorld);
expect(wrapper.vm.hello).toBe('Hello');
});
});
The first generic type (here I put any
) are the props type of your component and the second generic ({ bipbip: string }) are the types of your returned properties (what you return in a setup
function). With <script setup>
you can put directly all your variables.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.