node / vue.js单元测试带有promise,如何正确编写?

时间:2017-11-04 13:05:38

标签: node.js vue.js promise mocha sinon

基本上,我正在尝试测试以下vex / action:

export default {
  login (context, payload) {
    return vueAuthInstance.login(payload.user, payload.requestOptions)
    .then((response) => {
      if (JSON.stringify(response.data) !== '{}') {
        return true
      } else {
        return false
      }
    })
  }
}

我有依赖 vueAuthInstance 我需要存根/模拟... 它被调用,它有一个登录函数,有两个argments,它返回一个带有数据属性的对象(响应)

  vueAuthInstance = {login: sinon.stub().withArgs({email: 'email', password: 'password'}, 'options').return({data: 'user_data_with_token'}) }

我的登录功能实际上就像调用vueAuthInstance存根一样, 所以我应该可以写

actions.login(context, payload).then((response) => {
  expect(response).to.eql(true)
})

但我正在写一个正确的测试

describe('login', () => {
   const payload = {user: {email: 'john.doe@domain.com', password: 'john123'}}
   sinon.stub(vueAuthInstance, 'login').withArgs(payload).returns(true)
   it('should return successful login', () => {
     actions.login(context, payload).then((response) => {
       expect(response).to.eql(true)
     })
   })
 })

我收到错误:

 actions.js login
 TypeError: Cannot read property 'then' of undefined

完成上下文,这里是完整的文件......

@ / services / auth.js =======================

import Vue from 'vue'
import Vuex from 'vuex'
 aimport { VueAuthenticate } from 'vue-authenticate'
import axios from 'axios'

Vue.use(Vuex)
Vue.use(VueAxios, axios)

const vueAuthInstance = new VueAuthenticate(axios, {
  baseUrl: '/'
}) a

export default vueAuthInstance

@ / vuex / getters.js =======================

import _ from 'underscore'

export default {
  isAuthenticated: state => state.isAuthenticated,
}

@ / vuex / mutation_types.js =======================

export const IS_AUTHENTICATED = 'isAuthenticated'
export const CURRENT_USER_ID = 'currentUserId'

@ / vuex / actions.js =======================

  import { IS_AUTHENTICATED, CURRENT_USER_ID } from './mutation_types'
  import getters from './getters'
  import vueAuthInstance from '@/services/auth.js'

  login (context, payload) {
    payload = payload || {}
    return vueAuthInstance.login(payload.user, payload.requestOptions)
    .then(  login: ({ commit }, payload) => {
      payload = payload || {}
      return vueAuthInstance.login(payload.user, payload.requestOptions)
      .then((response) => {
        // check response user or empty
        if (JSON.stringify(response.data) !== '{}') {
          commit(IS_AUTHENTICATED, { isAuthenticated: true })
          commit(CURRENT_USER_ID, { currentUserId: response.data.id })
          return true
        } else {
          commit(IS_AUTHENTICATED, { isAuthenticated: false })
          commit(CURRENT_USER_ID, { currentUserId: '' })
          return false
        }
     })
   }

/test/unit/specs/vuex/actions.js =======================

  describe('login', () => {
    it('should return successful login', () => {
    })
  })

  1/ I must stub or spy my dependency vueAuthInstance

1 个答案:

答案 0 :(得分:0)

正如@Bergi所提到的,返回的对象应该是一个promise,所以正确的测试是:

      describe('loginUser', () => {
        var sandbox, payload, response
        beforeEach(() => {
          sandbox = sinon.sandbox.create()
        })
        afterEach(() => {
          sandbox.restore()
        })

        it('should return successful login', () => {
          payload = {user: {email: 'john.doe@domain.com', password: 'john123'}, requestOptions: {}}
          response = {data: {id: 1, name: 'John Doe', email: 'john.doe@domain.com', created_at: '2017-11-02T07:56:36.405Z', token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiSm9obiBMb2dpbiBEb2UiLCJhZG1pbiI6dHJ1ZX0.VHK2sCbj5nKJ8oC44UTHuhQHXEdPN8zjKjaFT0OZ-L'}}
          sandbox.stub(vueAuthInstance, 'login').withArgs(payload.user, payload.requestOptions).returns(Promise.resolve(response))

          return actions.login(store, payload)
          .then((result) => {
            expect(result).to.eql(true)
            expect(store.commit).to.have.been.calledWith(types.IS_AUTHENTICATED, { isAuthenticated: true })
            expect(store.commit).to.have.been.calledWith(types.CURRENT_USER_ID, { currentUserId: response.data.id })
          })
        })
       it('should return invalid login', () => {
          payload = {user: {email: 'john.doe@domain.com', password: 'john999'}, requestOptions: {}}
          response = {data: {}}
          sandbox.stub(vueAuthInstance, 'login').withArgs(payload.user, payload.requestOptions).returns(Promise.resolve(response))

          return actions.login(store, payload)
          .then((result) => {
            expect(result).to.eql(false)
            expect(store.commit).to.have.been.calledWith(types.IS_AUTHENTICATED, { isAuthenticated: false })
            expect(store.commit).to.have.been.calledWith(types.CURRENT_USER_ID, { currentUserId: '' })
          })
        })
      })