假设我有一个非常基本的 vue-class-component ,如下所示:
<template>
<div>Nothing of interest here</div>
</template>
<script>
import Vue from 'vue';
import Component from 'vue-class-component';
import http from './../modules/http';
@Component
export default class Example extends Vue {
user = null;
errors = null;
/**
* @returns {string}
*/
getUserId() {
return this.$route.params.userId;
}
fetchUser() {
this.user = null;
this.errors = null;
http.get('/v1/auth/user/' + this.getUserId())
.then(response => this.user = response.data)
.catch(e => this.errors = e);
}
}
</script>
我想测试fetchUser()
方法,因此我只是嘲笑'./../modules/http'
依赖项并让http.get
返回Promise
。问题是,在我的断言中,我想检查URL是否正确构建,为了做到这一点,用户ID必须来自测试中的硬编码变量。
我尝试了类似的东西,但它不起作用:
import ExampleInjector from '!!vue-loader?inject!./../../../src/components/Example.vue';
const mockedComponent = ExampleInjector({
'./../modules/http': {
get: () => new Promise(/* some logic */)
},
methods: getUserId: () => 'my_mocked_user_id'
});
不幸的是它不起作用,我在Vue文档中找不到任何特定内容,所以问题是,我应该如何模拟外部依赖项和类组件方法?
注意:我不想模仿this.$route.params.userId
因为userId
也可能来自其他地方(加上这只是一个例子)。我只是想模仿getUserId
方法。
答案 0 :(得分:2)
最简单的方法是扩展组件并覆盖方法:
const Foo = Vue.extend({
template: `<div>{{iAm}}</div>`,
created() {
this.whoAmI();
},
methods: {
whoAmI() {
this.iAm = 'I am foo';
}
},
data() {
return {
iAm: ''
}
}
})
Vue.component('bar', {
extends: Foo,
methods: {
whoAmI() {
this.iAm = 'I am bar';
}
}
})
new Vue({
el: '#app'
})
在此示例中,我使用extends
属性告诉Vue
Bar
扩展Foo
,然后我覆盖了whoAmI
方法,你可以在这里看到这是行动:https://jsfiddle.net/pxr34tuz/
我在我的一个开源项目中使用类似的东西,你可以查看here。我在该示例中所做的就是关闭道具所需的属性以阻止Vue向我抛出控制台错误。
答案 1 :(得分:2)
由于我特意询问我如何使用注入加载器模拟Vue类组件方法,这里是问题的完整解决方案:
import ExampleInjector from '!!vue-loader?inject!./../../../src/components/Example.vue';
const getComponentWithMockedUserId = (mockedUserId, mockedComponent = null, methods = {}) => {
if (!mockedComponent) {
mockedComponent = ExampleInjector();
}
return Vue.component('test', {
extends: mockedComponent,
methods: {
getUserId: () => mockedUserId,
...methods
}
});
};
然后在我的测试用例中:
const component = getComponentWithMockedUserId('my_mocked_user_id');
const vm = new Vue(component);
我发现当你需要创建一个部分模拟 AND 注入一些依赖项时,这非常有用。