簡體   English   中英

Vue.js(2.0)單元測試問題

[英]Vue.js (2.0) unit test issue

我正在嘗試使用Mocha和Sinon對vuex動作進行單元測試

這是我的action.spec.js

import actions from '@/vuex/actions'
import * as types from '@/vuex/mutation_types'

describe('actions.js', () => {
  var server, store, lists, successPut, successPost, successDelete

  successDelete = {'delete': true}
  successPost = {'post': true}
  successPut = {'put': true}

  beforeEach(() => {
    // mock shopping lists
    lists = [{
      id: '1',
      title: 'Groceries'
    }, {
      id: '2',
      title: 'Clothes'
    }]

    // mock store commit and dispatch methods
    store = {
      commit: (method, data) => {},
      dispatch: () => {
        return Promise.resolve()
      },
      state: {
        shoppinglists: lists
      }
    }
    sinon.stub(store, 'commit')

    // mock server
    server = sinon.fakeServer.create()
    server.respondWith('GET', /shoppinglists/, xhr => {
      xhr.respond(200, {'Content-Type': 'application/json'}, JSON.stringify(lists))
    })
    server.respondWith('POST', /shoppinglists/, xhr => {
      xhr.respond(200, {'Content-Type': 'application/json'}, JSON.stringify(successPost))
    })
    server.respondWith('PUT', /shoppinglists/, xhr => {
      xhr.respond(200, {'Content-Type': 'application/json'}, JSON.stringify(successPut))
    })
    server.respondWith('DELETE', /shoppinglists/, xhr => {
      xhr.respond(200, {'Content-Type': 'application/json'}, JSON.stringify(successDelete))
    })
    server.autoRespond = true
  })

  afterEach(() => {
    // restore stubs and server mock
    store.commit.restore()
    server.restore()
  })

  describe('populateShoppingLists', () => {
    it('should call commit method with POPULATE_SHOPPING_LIST string parameter', done => {
      actions.populateShoppingLists(store).then(() => {
        expect(store.commit).to.have.been.calledWith(types.POPULATE_SHOPPING_LISTS, lists)
        done()
      }).catch(done)
    })
  })

  describe('changeTitle', () => {
    it('should call commit method with CHANGE_TITLE string', (done) => {
      let title = 'new title'

      actions.changeTitle(store, {title: title, id: '1'}).then(() => {
        expect(store.commit).to.have.been.calledWith(types.CHANGE_TITLE, {title: title, id: '1'})
        done()
      }).catch(done)
    })
  })

  describe('updateList', () => {
    it('should return successful PUT response', (done) => {
      actions.updateList(store, '1').then((data) => {
        expect(data.data).to.eql(successPut)
        done()
      }).catch(done)
    })
  })

  describe('createShoppingList', () => {
    it('should return successful POST response', (done) => {
      let newList = { title: 'new list', id: '3' }
      actions.createShoppingList(store, newList).then((testResponse) => {
        console.log('testResponse: ', testResponse)
        expect(testResponse.body).to.eql(successPost)
        done()
      }).catch(done)
    })
  })
})

這是我的action.js

import { CHANGE_TITLE, POPULATE_SHOPPING_LISTS } from './mutation_types'
import api from '../api'
import getters from './getters'

export default {
  populateShoppingLists: ({ commit }) => {
    return api.fetchShoppingLists().then(response => {
      commit(POPULATE_SHOPPING_LISTS, response.data)
    })
  },

  changeTitle: (store, data) => {
    store.commit(CHANGE_TITLE, data)
    return store.dispatch('updateList', data.id)
  },

  updateList: (store, id) => {
    let shoppingList = getters.getListById(store.state, id)
    return api.updateShoppingList(shoppingList)
  },

  createShoppingList: (store, shoppinglist) => {
    return api.addNewShoppingList(shoppinglist).then((actionResponse) => {
      console.log('actionResponse: ', actionResponse)
      store.dispatch('populateShoppingLists')
    })
  },
}

運行我的單元測試, createShoppingList測試有問題

console.log

  actions.js
    populateShoppingLists
      ✓ should call commit method with POPULATE_SHOPPING_LIST string parameter
    changeTitle
      ✓ should call commit method with CHANGE_TITLE string
    updateList
      ✓ should return successful PUT response
LOG LOG: 'actionResponse: ', Response{url: 'http://localhost:3000/shoppinglists', ok: true, status: 200, statusText: 'OK', headers: Headers{map: Object{Content-Type: ...}}, body: Object{post: true}, bodyText: '{"post":true}'}
LOG LOG: 'testResponse: ', undefined
    createShoppingList
      ✗ should return successful POST response
        undefined is not an object (evaluating 'testResponse.body')
        webpack:///test/unit/specs/vuex/actions.spec.js:90:28 <- index.js:15508:28
        webpack:///~/vue-resource/dist/vue-resource.es2015.js:151:0 <- index.js:17984:52
        webpack:///~/vue/dist/vue.esm.js:701:0 <- index.js:3198:18
        nextTickHandler@webpack:///~/vue/dist/vue.esm.js:648:0 <- index.js:3145:16

whicj指示在createShoppingList操作中,不會在返回時發送回響應,因此Expect(testResponse.body).to.eql(successPost)不正確。

在這種情況下,我的Promise處理有什么問題?

感謝您的反饋

testResponse正確的軌道上testResponse undefined ,因為createShoppingList解析為addNewShoppingList.then的返回值,該值未指定,默認為undefined

如果createShoppingList解決與addNewShoppingList的響應或從響應populateShoppingLists 如果是前者, actionResponse處理程序返回actionResponse

return api.addNewShoppingList(shoppinglist).then((actionResponse) => {
  store.dispatch('populateShoppingLists')
  return actionResponse
});

作為一個側面說明,因為你正在測試的行動承諾,你可以擺脫done直接返回的動作在你的測試:

it('should call commit method with POPULATE_SHOPPING_LIST string parameter', () => {
  // mocha will fail the test if the promise chain rejects or the expectation is not met
  return actions.populateShoppingLists(store).then(() => {
    expect(store.commit).to.have.been.calledWith(types.POPULATE_SHOPPING_LISTS, lists)
  })
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM