单元测试vue组件,使用vue-cli,无法测试父方法?
Unit testing vue component, using vue-cli, can't test parent methods?
我正在 运行 解决这个我无法弄清楚的问题,环顾四周似乎找不到任何人问同样的问题...
所以,这是我的工作代码:
main.js:
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
window.Vue = Vue
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
methods: {
greetings: function () {
return 'good morning'
}
},
render: h => h(App)
})
router/index.js:
import Vue from 'vue'
import Router from 'vue-router'
import Configurations from '@/components/Configurations'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/configs',
name: 'Configurations',
component: Configurations
}
]
})
App.vue:
<template>
<router-view></router-view>
</template>
<script>
export default {
name: "App"
};
</script>
Configurations.vue:
<template>
<span>{{greetings}}</span>
</template>
<script>
export default {
name: "configurations",
data() {
return {
greetings: ""
};
},
created: function() {
this.greetings = this.$root.greetings();
}
};
</script>
当我 运行 时,它会显示一个页面,上面有 "good morning" 字样。没有其他的。如您所见,问候消息是在 main.js 文件中定义的,因为在这种情况下,我希望在所有组件上显示一条消息,即:版权说明。所以我将关于共同祖先的消息设置为我所有的组件。
根据我的理解,要从 "parent" 组件调用方法,您可以使用 this.$root.yourMethod() 来调用它。
现在,问题是,如果我想 运行 配置组件的单元测试,我会收到一个错误,这让我相信我的设置方式,我不能测试 this.$root.greetings() 因为有些东西告诉我测试环境不知道组件之间的父子关系。
所以,当我 运行:
cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run
设置了以下测试文件:
Configurations.spec.js:
import Configurations from '@/components/Configurations'
import Vue from 'vue'
describe('Configurations.vue', () => {
it('should display a greetings message', () => {
const Constructor = Vue.extend(Configurations)
const ConfigurationsComponent = new Constructor().$mount()
expect(ConfigurationsComponent.greetings).to.not.be.undefined;
})
})
我得到:
> 16 10 2018 09:28:35.184:INFO [karma]: Karma v1.7.1 server started at
> http://0.0.0.0:3000/ 16 10 2018 09:28:35.191:INFO [launcher]:
> Launching browser PhantomJS with unlimited concurrency 16 10 2018
> 09:28:35.204:INFO [launcher]: Starting browser PhantomJS 16 10 2018
> 09:28:40.977:INFO [PhantomJS 2.1.1 (Windows 8.0.0)]: Connected on
> socket WnDl-mQqmNZQOfyzAAAA with id 10303480 ERROR LOG: '[Vue warn]:
> Error in created hook: "TypeError: is not a constructor (evaluating
> 'this.$root.greetings()')"
(后面是堆栈溢出不允许我 post 的更多行,因为它们包含太多链接)
现在,如果我要改变
this.greetings = this.$root.greetings()
收件人:
this.greetings = "good morning";
在 Configurations.vue 文件中,然后再次 运行 测试命令,我会得到:
> 16 10 2018 09:48:43.174:INFO [karma]: Karma v1.7.1 server started at
> http://0.0.0.0:3000/ 16 10 2018 09:48:43.180:INFO [launcher]:
> Launching browser PhantomJS with unlimited concurrency 16 10 2018
> 09:48:43.555:INFO [launcher]: Starting browser PhantomJS 16 10 2018
> 09:48:49.228:INFO [PhantomJS 2.1.1 (Windows 8.0.0)]: Connected on
> socket o8BQ24wv1QX26SAZAAAA with id 53463701
>
> Configurations.vue
> √ should display a greetings message
>
> PhantomJS 2.1.1 (Windows 8.0.0): Executed 1 of 1 SUCCESS (0.024 secs / 0.017 secs)
>
> TOTAL: 1 SUCCESS
(后跟一些无关紧要的其他信息)
那么,我如何 运行 对包含调用 this.$root 方法的组件进行单元测试?
感谢任何帮助。
- 卢卡斯
您应该(几乎)永远不要从父组件中调用某些东西。
你有两种可能:
1. 使用 vuex store 并在那里保存你的数据。然后每一个需要的组件都可以通过一个store getter来访问它。
2. 将所需的数据作为 props 提供给您的子组件。
因为道具很快就会变得很乱,所以建议使用商店。
如果您这样做,您的测试将变得更加清晰易读。
使用模拟商店进行简单测试(只是为了展示事情的可能):
describe('MyComponent', () => {
let wrapper
beforeEach(() => {
const localVue = createLocalVue()
wrapper = mount(MyComponent, {
localVue,
mocks: {
$store: {
getters: {
'copyright': 'MyCopyright text'
}
}
}
})
})
it('should display copyright text', () => {
expect(wrapper.text('MyCopyright text')).toBe(true)
})
})
我正在 运行 解决这个我无法弄清楚的问题,环顾四周似乎找不到任何人问同样的问题...
所以,这是我的工作代码:
main.js:
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
window.Vue = Vue
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
methods: {
greetings: function () {
return 'good morning'
}
},
render: h => h(App)
})
router/index.js:
import Vue from 'vue'
import Router from 'vue-router'
import Configurations from '@/components/Configurations'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/configs',
name: 'Configurations',
component: Configurations
}
]
})
App.vue:
<template>
<router-view></router-view>
</template>
<script>
export default {
name: "App"
};
</script>
Configurations.vue:
<template>
<span>{{greetings}}</span>
</template>
<script>
export default {
name: "configurations",
data() {
return {
greetings: ""
};
},
created: function() {
this.greetings = this.$root.greetings();
}
};
</script>
当我 运行 时,它会显示一个页面,上面有 "good morning" 字样。没有其他的。如您所见,问候消息是在 main.js 文件中定义的,因为在这种情况下,我希望在所有组件上显示一条消息,即:版权说明。所以我将关于共同祖先的消息设置为我所有的组件。
根据我的理解,要从 "parent" 组件调用方法,您可以使用 this.$root.yourMethod() 来调用它。
现在,问题是,如果我想 运行 配置组件的单元测试,我会收到一个错误,这让我相信我的设置方式,我不能测试 this.$root.greetings() 因为有些东西告诉我测试环境不知道组件之间的父子关系。
所以,当我 运行:
cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run
设置了以下测试文件:
Configurations.spec.js:
import Configurations from '@/components/Configurations'
import Vue from 'vue'
describe('Configurations.vue', () => {
it('should display a greetings message', () => {
const Constructor = Vue.extend(Configurations)
const ConfigurationsComponent = new Constructor().$mount()
expect(ConfigurationsComponent.greetings).to.not.be.undefined;
})
})
我得到:
> 16 10 2018 09:28:35.184:INFO [karma]: Karma v1.7.1 server started at
> http://0.0.0.0:3000/ 16 10 2018 09:28:35.191:INFO [launcher]:
> Launching browser PhantomJS with unlimited concurrency 16 10 2018
> 09:28:35.204:INFO [launcher]: Starting browser PhantomJS 16 10 2018
> 09:28:40.977:INFO [PhantomJS 2.1.1 (Windows 8.0.0)]: Connected on
> socket WnDl-mQqmNZQOfyzAAAA with id 10303480 ERROR LOG: '[Vue warn]:
> Error in created hook: "TypeError: is not a constructor (evaluating
> 'this.$root.greetings()')"
(后面是堆栈溢出不允许我 post 的更多行,因为它们包含太多链接)
现在,如果我要改变
this.greetings = this.$root.greetings()
收件人:
this.greetings = "good morning";
在 Configurations.vue 文件中,然后再次 运行 测试命令,我会得到:
> 16 10 2018 09:48:43.174:INFO [karma]: Karma v1.7.1 server started at
> http://0.0.0.0:3000/ 16 10 2018 09:48:43.180:INFO [launcher]:
> Launching browser PhantomJS with unlimited concurrency 16 10 2018
> 09:48:43.555:INFO [launcher]: Starting browser PhantomJS 16 10 2018
> 09:48:49.228:INFO [PhantomJS 2.1.1 (Windows 8.0.0)]: Connected on
> socket o8BQ24wv1QX26SAZAAAA with id 53463701
>
> Configurations.vue
> √ should display a greetings message
>
> PhantomJS 2.1.1 (Windows 8.0.0): Executed 1 of 1 SUCCESS (0.024 secs / 0.017 secs)
>
> TOTAL: 1 SUCCESS
(后跟一些无关紧要的其他信息)
那么,我如何 运行 对包含调用 this.$root 方法的组件进行单元测试?
感谢任何帮助。
- 卢卡斯
您应该(几乎)永远不要从父组件中调用某些东西。
你有两种可能: 1. 使用 vuex store 并在那里保存你的数据。然后每一个需要的组件都可以通过一个store getter来访问它。 2. 将所需的数据作为 props 提供给您的子组件。
因为道具很快就会变得很乱,所以建议使用商店。
如果您这样做,您的测试将变得更加清晰易读。
使用模拟商店进行简单测试(只是为了展示事情的可能):
describe('MyComponent', () => {
let wrapper
beforeEach(() => {
const localVue = createLocalVue()
wrapper = mount(MyComponent, {
localVue,
mocks: {
$store: {
getters: {
'copyright': 'MyCopyright text'
}
}
}
})
})
it('should display copyright text', () => {
expect(wrapper.text('MyCopyright text')).toBe(true)
})
})