【发布时间】:2018-04-01 02:25:04
【问题描述】:
项目:https://github.com/marioedgar/webpack-unit-test
我有一个使用 vue CLI 生成的 Vue.js 应用程序。我只是稍微编辑了 HelloWorld 组件以从我的测试服务中获取一些异步数据,您可以在这里看到:
<template>
<h1>{{ message }}</h1>
</template>
<script>
import service from './test.service'
export default {
name: 'HelloWorld',
created () {
service.getMessage().then(message => {
this.message = message
})
},
data () {
return {
message: 'A'
}
}
}
</script>
<style scoped>
</style>
测试服务在同一个目录下,非常简单:
class Service {
getMessage () {
return new Promise((resolve, reject) => {
console.log('hello from test service')
resolve('B')
})
}
}
const service = new Service()
export default service
所以为了模拟这个服务,我使用 webpack vue-loader 来注入模拟服务,如官方文档中所述:
https://vue-loader.vuejs.org/en/workflow/testing-with-mocks.html
所以这是我的测试,几乎与示例相同:
import Vue from 'vue'
const HelloInjector = require('!!vue-loader?inject!../../../src/components/HelloWorld')
const Hello = HelloInjector({
// mock it
'./test.service': {
getMessage () {
return new Promise((resolve, reject) => {
resolve('C')
})
}
}
})
describe('HelloWorld.vue', () => {
it('should render', () => {
const vm = new Vue({
template: '<div><test></test></div>',
components: {
'test': Hello
}
}).$mount()
expect(vm.$el.querySelector('h1').textContent).to.equal('C')
})
})
我面临两个问题:
- 测试失败,因为断言在模拟的 Promise 解决之前执行。据我了解,这是因为当我进行断言时,vue 生命周期还没有完全完成。等待下一个周期的常见模式是将我的断言包装在下一个刻度函数周围,如下所示:
it('should render', (done) => {
const vm = new Vue({
template: '<div><test></test></div>',
components: {
'test': Hello
}
}).$mount()
Vue.nextTick(() => {
expect(vm.$el.querySelector('h1').textContent).to.equal('C')
done()
})
})
但是,除非我嵌套 3 个 nextTicks,否则这不起作用,这对我来说似乎非常 hacky。有什么我想念的东西来让它工作吗?这个例子看起来非常简单,但是如果没有很多 nextTicks,我就无法通过这个测试
- 我不断收到一个奇怪的错误,间歇性地...此警告可能出现 50% 的时间,而且完全不一致。
[vue warn] 组件挂载失败:模板或渲染函数未定义
同样,这种情况只是偶尔发生。我可以在不做任何更改的情况下运行完全相同的单元测试,并且它会在 50% 的情况下向我显示此消息。
【问题讨论】:
-
这里是我的公共仓库的链接:github.com/marioedgar/webpack-unit-test
标签: unit-testing vue.js