gpt4 book ai didi

javascript - 单元测试依赖全局事件总线的 Vue 组件

转载 作者:数据小太阳 更新时间:2023-10-29 04:49:00 26 4
gpt4 key购买 nike

我在全局 app.js 中声明了一个事件总线,如下所示:

window.Event = new Vue();

组件看起来像

export default {
data() {
return {
hasError: false,
zip: '',
};
},

methods: {
setZip: function() {
this.hasError = false;
this.$emit('setZip', this.zip);
},
},

mounted() {
Event.$on('showErrors', (errors) => {
this.hasError = errors.zip ? true : false;
});

this.zip = this.editZip;
},

props: [
'editZip'
],
}

我使用 ava 和以下 helpers/setup.js 对我的组件进行单元测试:

const browserEnv = require('browser-env');
const hook = require('vue-node');
const { join } = require('path');

// Setup a fake browser environment
browserEnv();

// Pass an absolute path to your webpack configuration to the hook function.
hook(join(__dirname, './webpack.config.js'));

webpack.config.js 看起来像:

module.exports = {
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.js', '.vue'],
},
};

运行以下测试时

import Vue from 'vue/dist/vue.js';
import test from 'ava';
import Zip from '../../resources/assets/js/components/Company/Zip.vue';

let vm;

test.beforeEach(t => {
let Z = Vue.extend(Zip);

vm = new Z({ propsData: {
editZip: 1220
}}).$mount();
});

test('that it renders a div with class form-group', t => {
t.is(vm.$el.className, 'form-group');
});

它通过了,但是抛出了以下错误:

[Vue warn]: Error in mounted hook: "TypeError: Event.$on is not a function"

(found in <Root>)
TypeError: Event.$on is not a function
at VueComponent.mounted (/mnt/c/code/leaflets/resources/assets/js/components/Company/City.vue:107:15)
at callHook (/mnt/c/code/leaflets/node_modules/vue/dist/vue.js:2530:21)
at mountComponent (/mnt/c/code/leaflets/node_modules/vue/dist/vue.js:2424:5)
at VueComponent.Vue$3.$mount (/mnt/c/code/leaflets/node_modules/vue/dist/vue.js:7512:10)
at VueComponent.Vue$3.$mount (/mnt/c/code/leaflets/node_modules/vue/dist/vue.js:9592:16)
at Test._ava2.default.beforeEach.t [as fn] (/mnt/c/code/leaflets/tests/js/CompanyCity.js:12:9)
at Test.callFn (/mnt/c/code/leaflets/node_modules/ava/lib/test.js:281:18)
at Test.run (/mnt/c/code/leaflets/node_modules/ava/lib/test.js:294:23)
at runNext (/mnt/c/code/leaflets/node_modules/ava/lib/sequence.js:58:44)
at Sequence.run (/mnt/c/code/leaflets/node_modules/ava/lib/sequence.js:90:10)
at Concurrent.run (/mnt/c/code/leaflets/node_modules/ava/lib/concurrent.js:41:37)
at runNext (/mnt/c/code/leaflets/node_modules/ava/lib/sequence.js:58:44)
at Sequence.run (/mnt/c/code/leaflets/node_modules/ava/lib/sequence.js:90:10)
at runNext (/mnt/c/code/leaflets/node_modules/ava/lib/sequence.js:58:44)
at Sequence.run (/mnt/c/code/leaflets/node_modules/ava/lib/sequence.js:90:10)
at Bluebird.try (/mnt/c/code/leaflets/node_modules/ava/lib/runner.js:214:48)
at tryCatcher (/mnt/c/code/leaflets/node_modules/bluebird/js/release/util.js:16:23)
at Function.Promise.attempt.Promise.try (/mnt/c/code/leaflets/node_modules/bluebird/js/release/method.js:39:29)
at Runner.run (/mnt/c/code/leaflets/node_modules/ava/lib/runner.js:214:22)
at process.on.options (/mnt/c/code/leaflets/node_modules/ava/lib/main.js:82:10)
at emitOne (events.js:96:13)
at process.emit (events.js:191:7)
at process.on.message (/mnt/c/code/leaflets/node_modules/ava/lib/process-adapter.js:14:10)
at emitTwo (events.js:106:13)
at process.emit (events.js:194:7)
at process.nextTick (internal/child_process.js:766:12)
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)

我不知道在我的测试中在哪里声明 window.Event = new Vue() ,以便被测试的组件可以访问 Event 变量。

最佳答案

首先,我建议从 window 对象中删除全局 EventBus(如果可以的话),因为依赖全局属性通常不是理想的,它可能会被代码的其他部分覆盖,从而导致不希望的结果效果。

您可以只创建一个 event-bus.js 文件并在其中创建事件总线:

import Vue from 'vue';
export const EventBus = new Vue();

然后您可以从需要访问事件总线的任何其他组件导入该文件,例如

import {EventBus} from '/path/to/event-bus.js'

从那里,您可以完全按照当前使用的方式使用它。

但是,如果出于某种原因必须将 EventBus 保留在窗口对象中,则还必须模拟它以便测试它。

首先,当您调用browserEnv 函数时,您需要mock the window object通过这样做:

browserEnv(['window']);

然后,window 将作为全局变量可用,但您需要更改组件的实现以显式地从 window 对象中获取 EventBus,例如:

window.EventBus

您还可以在组件中全局定义它,例如:

const { EventBus } = window

让我知道这是否有效。

谢谢,

关于javascript - 单元测试依赖全局事件总线的 Vue 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43886458/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com