使用 TypeScript SFC 测试 vue3 计算属性

Testing vue3 computed properties with TypeScript SFC

我正在尝试编写测试,使用 vitest, to assert a computed property in a vue3 component that is defined with script setup

考虑一个简单的组件:

// simple.vue
<script lang="ts" setup>
import { computed } from 'vue';

const hello = computed((): string => {
  return 'Hello';
});
</script>

<template>
  {{ hello }}
</template>

我的测试是这样的:

describe('Hello', () => {
  it('should compute hello', () => {
    const wrapper = mount(Hello);
    expect(wrapper.vm.hello).toBe('Hello');
  });
});

当 运行 使用 vitest 时,此测试实际上按预期工作,因此功能上似乎运行良好。

但是,VSCode 看不到 vm 对象的计算属性:

能够看到正常的属性(例如,用defineProps宏定义的属性)。这只是 VSCode 特定工具的问题,还是我应该使用另一种方法来测试 vue3 组件中的计算属性?

如果这是首选方法,是否可以引入计算属性的类型(类似于引入已定义道具的类型)?

我已经尝试过此 Vue Testing Handbook 中描述的技术,但这根本不起作用,我认为它必须特定于 vue2。

我假设您使用的 mount 来自 @vue/test-utils。 您可以像这样输入包装器以获得打字稿自动完成并且没有错误:

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');
  });
});


第一个泛型(我在这里放 any)是组件的道具类型,第二个泛型({ bipbip: string })是 returned 属性的类型(你在 setup 函数中 return 的内容)。使用 <script setup> 您可以直接放置所有变量。

来自Vue docs

Components using <script setup> are closed by default - i.e. 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>.

这也会影响 Vue Test Utils 中 wrapper.vm 的类型,因此它只包含 [=11] 的 public 或 exposed 道具=] 组件.

在您的情况下,使用 defineExpose() 编译器宏公开 hello:

<script lang="ts" setup>
import { computed } from 'vue';

const hello = computed((): string => {
  return 'Hello';
});
     
defineExpose({ hello });
</script>