简体   繁体   中英

Testing vue3 computed properties with TypeScript SFC

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM