单元测试一个打字稿vue组件

时间:2017-05-25 15:57:38

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

我需要能够测试我的组件(方法,计算属性,数据......)。但是,当我在单元测试中导入我的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为每个.d.ts文件生成.vue个文件,但遇到了this issue。此外,there is a request使.vue成为打字稿生态系统中的头等公民,这将消除此问题。而且,我刚刚添加了vue language service extension

的请求

1 个答案:

答案 0 :(得分: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)
  })
})