Vuex:使用 API 调用测试操作
Posted
技术标签:
【中文标题】Vuex:使用 API 调用测试操作【英文标题】:Vuex: Testing actions with API calls 【发布时间】:2017-05-22 18:49:24 【问题描述】:我一直在遵循these 测试指南来测试我的 vuex 商店。 但是当我谈到动作部分时,我觉得有很多我无法理解的事情。
第一部分是这样的:
// actions.js
import shop from '../api/shop'
export const getAllProducts = ( commit ) =>
commit('REQUEST_PRODUCTS')
shop.getProducts(products =>
commit('RECEIVE_PRODUCTS', products)
)
// actions.spec.js
// use require syntax for inline loaders.
// with inject-loader, this returns a module factory
// that allows us to inject mocked dependencies.
import expect from 'chai'
const actionsInjector = require('inject!./actions')
// create the module with our mocks
const actions = actionsInjector(
'../api/shop':
getProducts (cb)
setTimeout(() =>
cb([ /* mocked response */ ])
, 100)
)
我推断这是在操作内部模拟服务。
接下来的部分是:
// helper for testing action with expected mutations
const testAction = (action, payload, state, expectedMutations, done) =>
let count = 0
// mock commit
const commit = (type, payload) =>
const mutation = expectedMutations[count]
expect(mutation.type).to.equal(type)
if (payload)
expect(mutation.payload).to.deep.equal(payload)
count++
if (count >= expectedMutations.length)
done()
// call the action with mocked store and arguments
action( commit, state , payload)
// check if no mutations should have been dispatched
if (expectedMutations.length === 0)
expect(count).to.equal(0)
done()
describe('actions', () =>
it('getAllProducts', done =>
testAction(actions.getAllProducts, null, , [
type: 'REQUEST_PRODUCTS' ,
type: 'RECEIVE_PRODUCTS', payload: /* mocked response */
], done)
)
)
这是我难以理解的地方。
我的商店看起来像:
import * as NameSpace from '../NameSpace'
import ParseService from '../../Services/parse'
const state =
[NameSpace.AUTH_STATE]:
auth: ,
error: null
const getters =
[NameSpace.AUTH_GETTER]: state =>
return state[NameSpace.AUTH_STATE]
const mutations =
[NameSpace.AUTH_MUTATION]: (state, payload) =>
state[NameSpace.AUTH_STATE] = payload
const actions =
[NameSpace.ASYNC_AUTH_ACTION]: ( commit , payload) =>
ParseService.login(payload.username, payload.password)
.then((user) =>
commit(NameSpace.AUTH_MUTATION, auth: user, error: null)
)
.catch((error) =>
commit(NameSpace.AUTH_MUTATION, auth: [], error: error)
)
export default
state,
getters,
mutations,
actions
这就是我要测试的方式:
import * as NameSpace from 'src/store/NameSpace'
import AuthStore from 'src/store/modules/authorization'
const actionsInjector = require('inject!../../../../../src/store/modules/authorization')
// This file is present at: test/unit/specs/store/modules/authorization.spec.js
// src and test are siblings
describe('AuthStore Actions', () =>
const injectedAction = actionsInjector(
'../../Services/parse':
login (username, password)
return new Promise((resolve, reject) =>
setTimeout(() =>
if (Math.random() > 0.5)
resolve()
else
reject()
, 300)
)
)
it('Gets the user profile if the username and password matches', () =>
const testAction = (action, payload, state, mutations, done) =>
const commit = (payload) =>
if (payload)
expect(mutations.payload).to.deep.equal(payload)
action( commit, state , payload)
.then(result =>
expect(state).to.deep.equal(auth: result, error: null)
)
.catch(error =>
expect(state).to.deep.equal(auth: [], error: error)
)
testAction(injectedAction.login, null, , [])
)
)
如果我尝试这样做,我会得到:
"Gets the user profile if the username and password matches"
undefined is not a constructor (evaluating 'action( commit: commit, state: state , payload)')
"testAction@webpack:///test/unit/specs/store/modules/authorization.spec.js:96:13 <- index.js:26198:14
webpack:///test/unit/specs/store/modules/authorization.spec.js:104:15 <- index.js:26204:16"
我需要帮助了解我应该做什么来测试这些操作。
【问题讨论】:
【参考方案1】:我知道这已经有一段时间了,但我遇到了这个问题,因为我遇到了类似的问题。如果你在调用 testAction 之前 console.log injectionActions,你会看到 injectionAction 对象实际上是这样的:
Objectdefault: ObjectFUNC_NAME: function FUNC_NAME(_ref) ...
所以这里的主要解决方案是将 testAction 调用更改为:
testAction(injectedAction.default.login, null, , [], done)
因为您将您的操作导出为商店中的默认设置。
与您的特定错误无关的其他一些问题...您不需要操作 testAction 样板代码。只要您传入正确的参数,它就会按预期工作。此外,请务必将 done 传递给 testAction,否则您的测试将超时。希望这可以帮助遇到此问题的其他人!
【讨论】:
我还没有测试过这个,真的很忙。我会尽快接受你的回答。以上是关于Vuex:使用 API 调用测试操作的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Vuex 的操作中使用 axios 获取 Rest API 数据?