【问题标题】:How to stub Vue component methods for unit testing如何为单元测试存根 Vue 组件方法
【发布时间】:2020-05-25 18:44:19
【问题描述】:

如何从 Vue 单文件组件中存根某些方法(尤其是 getter)以使用 mocha/expect 进行单元测试?

我面临的问题如下: 我有一个带有 get 方法的组件 someData

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import SomeService from '@/services/some.service'

@Component()
export default class MyApp extends Vue {
    ...

    mounted () {
      ...
    }

    get someData () {
      return this.$route.path.split('/')[1] || 'main'
    }

    get getLocation () {
      return this.someService.getBaseURL()
    }

    initSomeStringProperty (): string {
      return 'some string'
    }
}
</script>

我的测试总是失败:

[Vue 警告]:渲染错误:“TypeError: Cannot read property 'path' of undefined”

当我尝试使用 sinon 存根方法时,如下所示:

describe('MyApp.vue', () => {
  if('returns main', () => {
    const dataStub = sinon.stub(MyApp, 'someData')
    listStub.yields(undefined, 'main')
    const wrapper = shallowMount(AppNavBar)
    expect(wrapper.text()).to.include('Some Content')
  })
})

但是,我收到以下错误:

TypeError: 不能存根不存在的自己的属性 someData

此外,对于所有其他方法,我都会遇到相同的错误,我想类似地存根,例如 initSomeStringProperty()。

【问题讨论】:

  • 它是一个 vue-class-component。请在上面编辑的问题中找到示例代码。

标签: unit-testing vue.js mocha.js sinon


【解决方案1】:

在上面的代码中,someData 是通过vue-property-decorator 使用属性访问器定义的计算属性。

它可以在两个点被存根,无论是在类原型上:

sinon.stub(MyApp.prototype, 'someData').get(() => 'foo');

或组件选项:

sinon.stub(MyApp.options.computed.someData, 'get').value('foo');

【讨论】:

    【解决方案2】:

    您可以设置组件的computed props and methods upon mounting,如下图所示。 更新:从 1.x 开始,设置方法已被 deprecated 支持存根(请参阅 @EstusFlask's answer,了解如何正确使用 Sinon 存根)。

    const wrapper = shallowMount(MyApp, {
      computed: {
        someData: () => 'foo'
      },
      methods: {
        initSomeStringProperty: () => 'bar'
      }
    })
    expect(wrapper.vm.someData).to.equal('foo')
    expect(wrapper.vm.initSomeStringProperty()).to.equal('bar')
    

    如果你只是想避免$route 未定义的错误,你可以mock $route upon mounting

    const wrapper = shallowMount(MyApp, {
      mocks: {
        $route: { path: '/home' }
      }
    })
    expect(wrapper.vm.someData).to.equal('home')
    

    【讨论】:

    • "通过methods 属性覆盖方法已被弃用,将在下一个主要版本中删除。methods 属性没有明确的迁移路径 - Vue 不支持任意替换方法, VTU 也不应该。要存根一个复杂的方法,从组件中提取它并单独测试它。否则,建议重新考虑这些测试。”
    • @VongarnichtsundStuff 添加了关于弃用的说明
    猜你喜欢
    • 1970-01-01
    • 2019-03-20
    • 2019-04-18
    • 1970-01-01
    • 2016-10-19
    • 2011-06-20
    • 2016-04-25
    • 1970-01-01
    • 2016-12-11
    相关资源
    最近更新 更多