Jeff
Jeff

Reputation: 309

Vue Test Mock Promise-Based Action within Module

I unfortunately can't attach all code or create a gist because the project I'm working on is related to work but I can give enough detail that I think it will work.

I'm trying to mock a call to an action that is stored in a different module but for the life of me I can't figure out how to. I'm able to create a Jest spy on the store.dispatch method but I want to be able to resolve the promise and make sure that the subsequent steps are taken.

The method in the SFC is

doSomething(data) {
  this.$store.dispatch('moduleA/moduleDoSomething',{data: data})
    .then(() => {
      this.$router.push({name: 'RouteName'})
    })
    .catch(err => {
      console.log(err)
      alert('There was an error.  Please try again.')

    })
},

This is what my test looks like:

import { mount, createLocalVue } from '@vue/test-utils'
import Vuex from 'vuex'
import Vuetify from 'vuetify'
import Component from '@/components/Component'
import moduleA from '@/store/modules/moduleA'

const localVue = createLocalVue()

localVue.use(Vuex)
localVue.use(Vuetify)

describe('Component.vue', () => {
  let actions
  let store

  const $router = []

  beforeEach(() => {
    actions = {
      moduleDoSomething: jest.fn((payload) => {
        return Promise.resolve({
          status: 200,
        })
     })
    }

    store = new Vuex.Store({
      state: {},
      modules: {
        moduleA: {
          actions
        }
      },
    })
  })

  it('does something', () => {
    const wrapper = mount(Component, {
      store,
      localVue,
      mocks: {
        $router,
      },
    })
    let button = wrapper.find('button that calls doSomething')
    button.trigger('click')
    expect(actions.moduleDoSomething).toHaveBeenCalled()
    expect(wrapper.vm.$router[0].name).toBe('RouteName')
  })
})

The following test passes, but I don't want to just test that the action was dispatched; I also want to test things in the "then" block.

  it('does something', () => {
    const dispatchSpy = jest.spyOn(store, 'dispatch')
    const wrapper = mount(Component, {
      store,
      localVue,
      mocks: {
        $router,
      },
    })
    let button = wrapper.find('button that calls doSomething')
    button.trigger('click')
    expect(dispatchSpy).toHaveBeenCalledWith('moduleA/moduleDoSomething',{data: data})
  })
})

Upvotes: 0

Views: 1750

Answers (1)

Jeff
Jeff

Reputation: 309

I managed to solve this problem by simply making the module namespaced in the mocked store.

store = new Vuex.Store({
  state: {},
  modules: {
    moduleA: {
      actions,
      namespaced: true
    }
  },
})

I'll delete the question in a little bit

Upvotes: 1

Related Questions