Vue.js单元测试 - 以异步数据
项目模拟服务:https://github.com/marioedgar/webpack-unit-testVue.js单元测试 - 以异步数据
我有我与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
所以为了给M
https://vue-loader.vuejs.org/en/workflow/testing-with-mocks.html
因此,这里是我的测试,是几乎相同的例子:
玉珠这项服务,因为官方文档在这里描述了使用的WebPack VUE装载机IM注入模拟服务
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')
})
})
有两个问题我面对:
- 测试失败,因为断言在解决模拟诺言之前正在执行。根据我的理解,这是因为当我进行断言时,vue生命周期还没有完全完成。常见的图案,以等待下一个周期将是wrapp周围跟旁边剔功能像这样我的说法:
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 ,这对我来说似乎非常黑客。有什么我错过了让这个工作?这个例子似乎非常简单,但我不能让这个测试通过,而不很多nextTicks的
- 我不断收到一个奇怪的错误,间歇性地......这样的警告显示出来的时间大概50%,在不洽所有。
[VUE警告]无法安装部件:模板或呈现功能没有被定义
再次,这仅发生有时。我可以在没有任何更改的情况下运行相同的单元测试,并且会在50%的时间内向我显示此消息。
我真的无法弄清楚为什么有时组件未能挂载。我甚至不确定它是否与注射器有关,但无论如何,我通过不使用它来保持测试一致;改为尝试不同的方法。
如果服务通过props
注入而不是直接使用,则该组件可能更易于测试。
<template>
<div>
<h1>{{ message }}</h1>
</div>
</template>
<script>
import service from './test.service'
export default {
name: 'HelloWorld',
created() {
this.service.getMessage().then(message => {
this.message = message
})
},
data() {
return {
message: 'A'
}
},
props: {
service: {
default: service
}
}
}
</script>
<style scoped>
</style>
这使得喷射器不必要的,因为嘲笑服务可以代替传递给在构造使用propsData
的组件。
import Vue from 'vue'
import Async from '@/components/Async'
const service = {
getMessage() {
return new Promise((resolve, reject) => {
resolve('C')
})
}
}
describe('Async.vue',() => {
let vm
before(() => {
const Constructor = Vue.extend(Async)
vm = new Constructor({
propsData: {
service: service
}
}).$mount()
})
it('should render', function() {
// Wrapping the tick inside a promise, bypassing PhantomJS's lack of support
return (new Promise(resolve => Vue.nextTick(() => resolve()))).then(() => {
expect(vm.$el.querySelector('h1').textContent).to.equal('C')
})
})
})
我喜欢这比使用注射器,这并解决的问题之一我正面临着。不幸的是,额外的蜱是必要的。我想知道是否可以在before()中做到这一点,以避免在每个测试中的所有额外的代码。这或我可以添加一个简单的异步帮助器功能。 –
你是对的。使用摩卡的'之前'测试只能进入组件,直到完全安装的组件,所以只需要一个滴答。我改变了代码来反映这一点。 –
这里是链接到我的公共回购: https://github.com/marioedgar/webpack-unit-test –