Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stubbing vuex getters with sinonjs

On my application, inside a navigation guard used by my router, I have a vuex namespaced getter to check authentication state. The getter do the magic underlaying check if the user is authenticated.

I want to write a simple unit test which check that the redirection is done according to the authenticated state. I'm stucked on stubbing the getter.

My getter is the following :

isAuthenticated (state) {
  return state.token !== null
}

My authentication module is the following :

export default {
    namespaced: true,
    state,
    getters
}

And my store is the following :

export default new Vuex.Store({
    modules: {
        authentication
     }
})

My naviguation guard is :

import store from '@/store'

export default (to, from, next) => {
  if (store.getters['authentication/isAuthenticated']) {
    next()
    return
  }

  next({name: 'login'})
}

I've wrote that unit test :

   describe('authenticated-guard.spec.js', () => {
      let authenticatedStub
      beforeEach(() => {
        authenticatedStub = sandbox.stub(store.getters, 'authentication/isAuthenticated')
      })

      afterEach(() => {
        sandbox.restore()
      })

      it('should redirect to login route when the user is not authenticated', () => {
        // Given
        const to = {}
        const from = {}
        const next = spy()
        authenticatedStub.value(false)

        // When
        authenticatedGuard(to, from, next)

        // Then
        assert.ok(next.calledWith({name: 'login'}), 'should have redirected to login route')
      })
    })

The unit test trigger the following error : TypeError: Cannot redefine property: authentication/isAuthenticated.

I've tried as an alternative to stub using authenticatedStub.value(false) but the error is the same. I'm unable to stub the getter to avoid to have store logics on guard tests.

Does someone beeing able to stub any getter outside of components ?

Regards

like image 668
clement.michelet Avatar asked Oct 16 '17 13:10

clement.michelet


1 Answers

The problem is that vuex sets the getters as non-configurable properties, so they can't be changed.

A way to stub them is to stub the getters object itself so your test could work like this:

describe('authenticated-guard.spec.js', () => {
  it('should redirect to', () => {
    const authenticatedStub = sandbox.stub(store, 'getters')
    // Given
    const to = {}
    const from = {}
    const next = spy()
    authenticatedStub.value({
      'authentication/isAuthenticated': false
    })

    // When
    authenticatedGuard(to, from, next)

    // Then
    expect(next.lastCall.args).to.deep.equal([{name: 'login'}], 'login route when the user is not authenticated')

    authenticatedStub.value({
      'authentication/isAuthenticated': true
    })

    authenticatedGuard(to, from, next)

    expect(next.lastCall.args).to.deep.equal([], 'next route when the user is authenticated')
  })
})
like image 157
Luis Orduz Avatar answered Nov 13 '22 02:11

Luis Orduz