Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test if Vuex action has been dispatched in VueJS

I just want to test if myAwesome action is dispatched when my App.vue component is created(). Is this something you would test? I'm using Jasmine for these tests. Any help would be awesome!

App.js

describe('when app is created()', () => {
  it('should dispatch myAwesomeAction', (done) => {

    const actions = {
      myAwesomeAction() {
        console.log('myAwesomeAction')
        // commit()
      }
    }

    const state = {
      myAwesomeAction: false
    }

    const mutations = {
      LOAD_SUCCESS(state) {
        state.myAwesomeAction = true
      }
    }

    const options = {
      state,
      mutations,
      actions
    }

    const mockStore = new Vuex.Store(options)

    spyOn(mockStore, 'dispatch')

    const vm = new Vue({
      template: '<div><component></component></div>',
      store: mockStore,
      components: {
        'component': App
      }
    }).$mount()

    Vue.nextTick(() => {
      expect(mockStore.dispatch).toHaveBeenCalled()
      expect(mockStore.dispatch).toHaveBeenCalledWith('myAwesomeAction')
      done()
    })
  })
})

Errors:

1) should dispatch myAwesomeAction
     App
     Expected spy dispatch to have been called.
webpack:///src/views/App/test/App.spec.js:49:6 <- index.js:50916:50
webpack:///~/vue/dist/vue.esm.js:505:15 <- index.js:3985:24
nextTickHandler@webpack:///~/vue/dist/vue.esm.js:454:0 <- index.js:3934:16
     Expected spy dispatch to have been called with [ 'loadOrganisation' ] but it was never called.
webpack:///src/views/App/test/App.spec.js:50:54 <- index.js:50918:54
webpack:///~/vue/dist/vue.esm.js:505:15 <- index.js:3985:24
nextTickHandler@webpack:///~/vue/dist/vue.esm.js:454:0 <- index.js:3934:16
like image 855
Dryden Williams Avatar asked May 06 '17 00:05

Dryden Williams


People also ask

How do I dispatch an action from action in Vuex?

You can call another Vuex action by passing the name of that action as a string as the first argument of dispatch : const store = new Vuex. Store({ actions: { walk(context) { context. dispatch("goForward"); }, goForward(context) { // }, }, });

Does Vuex Dispatch return a promise?

In Vuex actions are asynchronous. If an action is complete , there is no way to detect that. You can return a Promise to let the calling function know that the action is complete.

What is difference between dispatch and commit in Vuex?

Dispatch triggers an action whereas commit triggers a mutation. $dispatch is always used from your methods in routes/components. It sends a message to Vuex store to perform some action. The action can be performed any time after the current tick so that it will not affect the frontend performance.

How do you test a Vuex store?

There are two approaches to testing a Vuex store. The first approach is to unit test the getters, mutations, and actions separately. The second approach is to create a store and test against that.


1 Answers

The thing is, you are trying to unit test a store from a component, so there's a little bit of a problem when you are mocking some elements and relying in true functionality in other elements. I'm no expert in vuex, I had a similar problem trying to spy on a store action and call a component's method (can't remember what the problem was, i remember i did waste half a day with it).

My suggestion: test component as unit, then test store module as unit, that means in your app component you can spy

spyOn(vm, 'myAwesomeAction');
Vue.nextTick(() => {
    expect(vm.myAwesomeAction).toHaveBeenCalled()
    done()
});

(that is, check if initializing your component, your method that calls the store action is called, in my example myawesomeaction will be a mapAction name in the methods object)

And then, you can unit test your store, and check that if you call myawesomeaction the mutation on that component will occur

check the test action helper here: https://vuex.vuejs.org/en/testing.html

like image 120
Gerardo Rosciano Avatar answered Sep 20 '22 13:09

Gerardo Rosciano