使用 sinonjs 存根 vuex getter

Posted

技术标签:

【中文标题】使用 sinonjs 存根 vuex getter【英文标题】:Stubbing vuex getters with sinonjs 【发布时间】:2018-03-28 00:34:12 【问题描述】:

在我的应用程序中,在路由器使用的导航守卫内,我有一个 vuex 命名空间的 getter 来检查身份验证状态。 getter 执行神奇的底层检查用户是否已通过身份验证。

我想编写一个简单的单元测试来检查重定向是否根据经过身份验证的状态完成。我一直坚持对 getter 进行存根。

我的吸气剂如下:

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

我的认证模块如下:

export default 
    namespaced: true,
    state,
    getters

我的商店如下:

export default new Vuex.Store(
    modules: 
        authentication
     
)

我的导航守卫是:

import store from '@/store'

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

  next(name: 'login')

我已经编写了那个单元测试:

   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')
      )
    )

单元测试触发如下错误:TypeError: Cannot redefine property: authentication/isAuthenticated.

我已尝试使用authenticatedStub.value(false) 作为存根的替代方法,但错误是相同的。 我无法对 getter 进行存根以避免在警戒测试中存储逻辑。

是否有人能够对组件之外的任何 getter 进行存根?

问候

【问题讨论】:

【参考方案1】:

问题在于 vuex 将 getter 设置为不可配置的属性,因此无法更改。

存根它们的一种方法是存根 getters 对象本身,这样您的测试就可以像这样工作:

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')
  )
)

【讨论】:

以上是关于使用 sinonjs 存根 vuex getter的主要内容,如果未能解决你的问题,请参考以下文章

在节点环境中存根 jQuery.ajax (jQuery 2.x)

如何在 node.js 中存根 process.env?

Vuex - 何时使用 getter 以及何时使用状态

Vuex--getters属性的使用

变异后VueX Getter没有运行

如何在Vuex的getter函数中调用getter函数