2017-01-08 2 views
3

Я слежу за правилами тестирования these, чтобы проверить свой магазин vuex. Но когда я коснулся части действия, я чувствовал, что происходит много, что я не мог понять.Vuex: Тестирование с помощью API-вызовов

Первая часть идет как:

// 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)') 
"[email protected]:///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

Я знаю, что прошло некоторое время, но я столкнулся с этим вопросом, потому что у меня была аналогичная проблема. Если бы вы были console.log injectedActions прямо перед вами делаете testAction называть вы бы увидели, что объект injectedAction на самом деле выглядит следующим образом:

Object{default: Object{FUNC_NAME: function FUNC_NAME(_ref) { ... }}}

Так основное решение здесь будет изменение вызова testAction к:

testAction(injectedAction.default.login, null, {}, [], done)

, потому что вы экспортируете ваши действия как значения по умолчанию в вашем магазине.

Некоторые другие проблемы, которые не связаны с вашей конкретной ошибкой ... Вам не нужно манипулировать тестовым кодом testAction. Он будет работать так, как ожидалось, до тех пор, пока вы передадите правильные параметры. Кроме того, обязательно перейдите к testAction или ваш тест истечет. Надеюсь, это поможет кому-то другому, кто сталкивается с этим!

+0

Я еще не тестировал это, был действительно занят работой. Я приму свой ответ, как только смогу проверить. –

Смежные вопросы