ptk
ptk

Reputation: 7623

Testing Vue Single File Components which use a Global Event Bus

I'm testing my Vue components for the first time using Mocha and Webpack and set everything up according to the docs.

However, in many of my components, I use a global event bus to communicate and emit events between components. For example, the following snippet is in the created hook of one of my single file components.

created() {
            Event.$on("activate-edit-modal", (listing) => {
                this.isModalActive = true; // show delete modal
                this.listing = listing; // set listing as the emitted listing
            });
        },

Unfortunately, when I run the following test code in my test file (npm run test), I get the following error.

import { mount } from '@vue/test-utils';
import editModal from '../../../src/components/admin/editModal.vue';

const wrapper = mount(editModal);
console.log(wrapper);

Error Msg: I'm aware the error msg is referring to the created hook (in the code snippet above) and highlighting that "Event.$on" in that created hook is not a function.

WEBPACK Compiled successfully in 2331ms

MOCHA Testing...

[Vue warn]: Error in config.errorHandler: "TypeError: Event.$on is not a function" TypeError: Event.$on is not a function at VueComponent.created ...

How should I test my components that use a global event bus? Note that I am not interested in testing the event bus itself; however, I'm unaware on how I can proceed to test other aspects of the component with this error.

The global event bus "Event" that I use in all my components is declared in /src/main.js as shown below

import Vue from 'vue';
import App from './App.vue';
import router from "./router";
import store from "./store";

window.Event = new Vue();

let app = new Vue({
    el: '#app',
    router,
    store,
    render: h => h(App)
});

Upvotes: 3

Views: 1160

Answers (3)

Mattias
Mattias

Reputation: 1131

You're trying to reference a local event bus called Event. You should call the bus you registered on the window object, like this: window.Event.$on("activate-edit-modal"....

After you've ensured that your component is calling the bus registered on the window object as shown above, make sure you also add the following before you mount your component in the test file like so:

import Vue from 'vue';

window.Event = new Vue();
const wrapper = mount(adminResults);

Upvotes: 3

Dave
Dave

Reputation: 6652

You can mock your event bus and assert that methods are called on it with correct parameters.

For instance, in the above scenario try window.Event = { $on: sinon.spy() }.

After mounting you should be able to assert that $on was called with correct parameters.

Here's documentation on Mocha and spies. https://github.com/mochajs/mocha/wiki/Spies

I'm not as familiar with mocha so I'm not exactly sure I've got the details correct.

Upvotes: 1

bbsimonbb
bbsimonbb

Reputation: 28992

Your global event bus "Event": where is it defined? I can't see it being imported anywhere into the component with the error. I suspect this is your problem.

Beware global event bus is a top five antipattern, according to one of the presentations at the recent vue conf. I much prefer a plain global javascript object as a global state store.

Upvotes: 1

Related Questions