Mocha 테스트에서 VueX 스토어를 라우터에 Import할 수 없음
업데이트 2
VueX git repo에서 작성된 문제에 대한 링크: https://github.com/vuejs/vuex/issues/1509
복제할 수 있는 레포 링크: https://github.com/djam90/vuex-vue-router-issue
업데이트:
이 문제는 VueX의 이 코드에서 발생합니다.여기서 rawModule은undefined
그리고 열쇠는getters
점포는 라우터를 수입하고 라우터는 스토어를 수입하는 순환 의존관계 때문이라고 생각합니다.
function assertRawModule (path, rawModule) {
Object.keys(assertTypes).forEach(function (key) {
debugger;
if (!rawModule[key]) { return }
var assertOptions = assertTypes[key];
forEachValue(rawModule[key], function (value, type) {
assert(
assertOptions.assert(value),
makeAssertionMessage(path, key, type, value, assertOptions.expected)
);
});
});
}
프로젝트에서는 Vue CLI 3을 사용하여 Vue, Vue Router, VueX 및 Mocha를 테스트에 사용합니다.
라우터를 스토어에 Import할 필요가 있지만 스토어를 라우터에 Import할 필요도 있습니다.브라우저에서 앱을 실행하면 정상적으로 동작하지만 스토어 또는 라우터를 테스트에 Import하면 다음과 같은 오류가 발생합니다.
MOCHA Testing...
RUNTIME EXCEPTION Exception occurred while loading your tests
TypeError: Cannot read property 'getters' of undefined
at /home/dan/code/garage/ui/dist/webpack:/node_modules/vuex/dist/vuex.esm.js:261:1
at Array.forEach (<anonymous>)
at assertRawModule (/home/dan/code/garage/ui/dist/webpack:/node_modules/vuex/dist/vuex.esm.js:260:1)
at ModuleCollection.register (/home/dan/code/garage/ui/dist/webpack:/node_modules/vuex/dist/vuex.esm.js:186:1)
at /home/dan/code/garage/ui/dist/webpack:/node_modules/vuex/dist/vuex.esm.js:200:1
at /home/dan/code/garage/ui/dist/webpack:/node_modules/vuex/dist/vuex.esm.js:75:44
at Array.forEach (<anonymous>)
at forEachValue (/home/dan/code/garage/ui/dist/webpack:/node_modules/vuex/dist/vuex.esm.js:75:1)
at ModuleCollection.register (/home/dan/code/garage/ui/dist/webpack:/node_modules/vuex/dist/vuex.esm.js:199:1)
at new ModuleCollection (/home/dan/code/garage/ui/dist/webpack:/node_modules/vuex/dist/vuex.esm.js:160:1)
at new Store (/home/dan/code/garage/ui/dist/webpack:/node_modules/vuex/dist/vuex.esm.js:311:1)
at Module../src/store/store.js (/home/dan/code/garage/ui/dist/webpack:/src/store/store.js:12:16)
at __webpack_require__ (/home/dan/code/garage/ui/dist/webpack:/webpack/bootstrap:25:1)
at Module../src/router.js (/home/dan/code/garage/ui/dist/webpack:/src/router.js:1:1)
at __webpack_require__ (/home/dan/code/garage/ui/dist/webpack:/webpack/bootstrap:25:1)
at Module../src/store/modules/bookings.js (/home/dan/code/garage/ui/dist/webpack:/src/store/modules/bookings.js:1:1)
at __webpack_require__ (/home/dan/code/garage/ui/dist/webpack:/webpack/bootstrap:25:1)
at Module../tests/unit/store/bookings.spec.js (/home/dan/code/garage/ui/dist/webpack:/tests/unit/store/bookings.spec.js:1:1)
at __webpack_require__ (/home/dan/code/garage/ui/dist/webpack:/webpack/bootstrap:25:1)
at run (/home/dan/code/garage/ui/dist/webpack:/node_modules/mocha-webpack/lib/entry.js:3:20)
at Array.forEach (<anonymous>)
at Object../node_modules/mocha-webpack/lib/entry.js (/home/dan/code/garage/ui/dist/webpack:/node_modules/mocha-webpack/lib/entry.js:10:1)
at __webpack_require__ (/home/dan/code/garage/ui/dist/webpack:/webpack/bootstrap:25:1)
at /home/dan/code/garage/ui/dist/webpack:/webpack/bootstrap:116:1
at Object.<anonymous> (/home/dan/code/garage/ui/dist/main.js:120:10)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object._module2.default._extensions.(anonymous function) [as .js] (/home/dan/code/garage/ui/node_modules/mocha-webpack/lib/util/registerRequireHook.js:148:12)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at /home/dan/code/garage/ui/node_modules/mocha/lib/mocha.js:250:27
at Array.forEach (<anonymous>)
at Mocha.loadFiles (/home/dan/code/garage/ui/node_modules/mocha/lib/mocha.js:247:14)
at Mocha.run (/home/dan/code/garage/ui/node_modules/mocha/lib/mocha.js:576:10)
라우터는 다음과 같습니다.
import Vue from 'vue'
import Router from 'vue-router'
import store from '@/store/store'
import storage from '@/services/storage'
import Login from './views/Login.vue'
import Dashboard from './views/Dashboard.vue'
import Bookings from './views/Bookings'
Vue.use(Router)
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/login',
name: 'login',
meta: {
layout: 'login'
},
component: Login
},
{
path: '/',
name: 'home',
component: Dashboard
},
{
path: '/bookings',
name: 'bookings',
component: Bookings
}
]
})
router.beforeEach((to, from, next) => {
const token = storage.get('token')
if (token && !store.state.auth.token) {
store.commit('auth/setAuthToken', token)
}
next()
})
export default router
다음은 매장 예약 모듈입니다.
import api from '@/api/bookings'
import router from '@/router'
const state = {
bookings: [],
lastAdded: null,
lastEdited: null,
errors: {
get: null,
add: null,
edit: null,
getById: null
},
booking: {}
}
export const getters = {
booking: state => {
return state.booking
}
}
export const actions = {
async getAll ({ commit }) {
try {
const response = await api.getAll()
commit('SET_BOOKINGS', response.data)
} catch (e) {
commit('SET_ERROR_FOR_GET', e)
}
},
async create ({ commit, state }, { booking }) {
try {
const response = await api.create(booking)
commit('SET_LAST_CREATED', response.data)
router.push({ name: 'bookings' })
} catch (e) {
commit('SET_ERROR_FOR_CREATE', e)
}
},
async getById ({ commit, state }, { id }) {
try {
const response = await api.getById(id)
commit('SET_BOOKING', response.data)
} catch (e) {
commit('SET_ERROR_FOR_GET_BY_ID', e)
}
}
}
export const mutations = {
SET_VEHICLES (state, vehicles) {
state.all = vehicles
},
SET_ERROR_FOR_GET (state, error) {
state.errors.get = error
},
SET_LAST_CREATED (state, customer) {
state.lastAdded = customer
},
SET_ERROR_FOR_CREATE (state, error) {
state.errors.add = error
},
SET_BOOKING (state, vehicle) {
state.vehicle = vehicle
},
SET_ERROR_FOR_GET_BY_ID (state, error) {
state.errors.getById = error
}
}
export default {
namespaced: true,
state,
getters,
actions,
mutations
}
제 테스트는 다음과 같습니다.
import chai from 'chai'
import sinon from 'sinon'
import sinonChai from 'sinon-chai'
import bookingsStore from '@/store/modules/bookings'
import api from '@/api/bookings'
// import router from '@/router'
import { stubBooking } from '../stubs/stubs'
chai.use(sinonChai)
const expect = chai.expect
const { getters, actions, mutations } = bookingsStore
// test getters
describe('getters', () => {
describe('booking', () => {
it('should return booking from state', () => {
const state = {
booking: {}
}
const actual = getters.booking(state)
expect(actual).to.deep.equal(state.booking)
})
})
})
// test actions
describe('actions', () => {
describe('create', () => {
let apiStub
let routerStub
beforeEach(() => {
apiStub = sinon.stub(api, 'create')
routerStub = sinon.stub(router, 'push')
})
afterEach(() => {
apiStub.restore()
routerStub.restore()
})
it('create success', async () => {
const commit = sinon.spy()
const state = {}
apiStub.resolves({
data: stubBooking
})
await actions.create({ commit, state }, { stubBooking })
expect(commit.args).to.deep.equal([
['SET_LAST_CREATED', stubBooking]
])
expect(router.push).to.have.been.called
})
})
})
보다시피, 그냥...import bookingsStore from '@/store/modules/bookings'
내 테스트에서 오류가 발생합니다.이것을 제거하면 테스트는 정상적으로 실행됩니다.
라우터에 Import 했을 때 스토어가 정의되어 있지 않은 것과 같은 문제가 있었습니다.
최종적으로 라우터 인스턴스 자체를 사용하여 스토어에 액세스하기로 했습니다.
router.beforeEach((to, from, next) => {
console.log('authenticated?', router.app.$store.getters['auth/isAuthenticated'])
// ...
})
Namesched 스토어를 사용하고 있기 때문에, 그것이 문제인 것 같습니다.어쨌든 저는 이 솔루션이 상당히 마음에 듭니다.
언급URL : https://stackoverflow.com/questions/54691789/unable-to-import-vuex-store-into-router-and-router-into-store-in-mocha-tests
'IT이야기' 카테고리의 다른 글
Linux에서 PATH_MAX는 어디에 정의되어 있습니까? (0) | 2022.06.04 |
---|---|
Laravel Echo 500 오류(브로드캐스트/인증) (0) | 2022.06.03 |
순수 VUE 구성 요소에 스타일 추가 (0) | 2022.06.03 |
Android는 간단한 애니메이션을 추가하면서 setvisibility(뷰)를 제공합니다.사라지다) (0) | 2022.06.03 |
포인터 표현식: *ptr++, *+ptr 및 ++*ptr (0) | 2022.06.03 |