【问题标题】:Unit test a typescript vue component单元测试一个打字稿vue组件
【发布时间】:2017-10-26 08:38:27
【问题描述】:

我需要能够测试我的组件(方法、计算属性、数据……)。但是,当我在单元测试中导入我的 vue 组件时:

import Pagination from 'src/components/shared/pagination.vue'
import { newComponent } from '../component-factory'

describe('pagination.vue', () => {
    const propsData = {
        metadata: {
            page: 2,
            records: 155,
            total: 11,
        },
        perPage: 15,
    }

    it('should have correct number of records', () => {
        const ctor = Vue.extend(Pagination)
        const vm = new ctor({propsData}).$mount()
        expect(vm.firstRecord).toBe(16)
        expect(vm.lastRecord).toBe(30)
    })
...

vm 的类型为 Vue,因此没有 firstRecord/lastRecord 属性。使用 karma 运行测试显示成功,但 typescript 编译器吐出错误:

ERROR in ./tests/shared/pagination.spec.ts
(16,19): error TS2339: Property 'firstRecord' does not exist on type 'Vue'.

ERROR in ./tests/shared/pagination.spec.ts
(17,19): error TS2339: Property 'lastRecord' does not exist on type 'Vue'.

我尝试过投射:

...
        const vm = new ctor({propsData}).$mount() as Pagination
...

但这会导致 VSCode 中出现警告:

[ts] Cannot find name 'Pagination'.

并且具有将vm 视为any 类型的效果,这完全适得其反。

我认为这一切都源于使用.vue文件时必须添加声明:

declare module '*.vue' {
    import Vue from 'vue'
    export default typeof Vue
}

这清楚地将所有.vue 文件的类型设置为Vue,这不是完全 谎言,但也没有帮助......有什么建议吗?我做错了什么?

为了将来参考,我尝试使用 vuetype 为每个.vue 文件生成.d.ts 文件,但遇到了this issue。此外,there is a request 使 .vue 成为打字稿生态系统中的一等公民,这将消除这个问题。而且,我刚刚添加了一个vue language service extension的请求

【问题讨论】:

    标签: unit-testing typescript jasmine vue.js karma-runner


    【解决方案1】:

    在 Vue 2.5 之前,如果您不打算使用 vue-class-component,他们的 TypeScript 文档页面建议导出扩展 Vue 的接口。您可以导出此接口以在您的测试中使用,以转换您的组件实例。该建议已从文档中删除,但我无法弄清楚如何将我的测试更改为不需要接口。

    看起来 vuetype 可以为你生成这些接口,但我只是手动创建它们。

    这是一个大大简化的示例,但您可以在界面中定义任何您将在 vm 上引用的内容,即数据、道具、方法:

    // NOTE: Make sure your interface extends `Vue`!
    export interface PaginationComponent extends Vue {
      firstRecord: number,
      lastRecord: number
    }
    
    export default {
      name: 'Pagination',
      data: function() {
        return {
          firstRecord: 16,
          lastRecord: 30,
        }
      }
    }
    

    对于您的测试,您可以将组件实例转换为导出接口的类型:

    import Pagination, {PaginationComponent} from 'src/components/shared/pagination.vue'
    
    describe('pagination', () => {
      it('should know about component data fields', () => {
        const ctor = Vue.extend(Pagination)
        const vm : PaginationComponent = new ctor().$mount()
        expect(vm.firstRecord).toBe(16)
        expect(vm.lastRecord).toBe(30)
      })
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-05
      • 2019-04-18
      • 2018-09-06
      • 2021-10-20
      • 2020-12-02
      • 2019-01-02
      • 2020-01-20
      • 2019-09-08
      相关资源
      最近更新 更多