vue 컴포넌트의 $route 개체를 모킹하는 쓰기 테스트 방법
다음과 같은 스테이트먼트를 포함하는 컴포넌트가 있습니다.this.$route.fullPath
, 의 가치를 어떻게 조롱해야 하는가?fullPath
의$route
그 컴포넌트를 테스트하려면 어떻게 해야 합니까?
나는 상위 대답에 동의하지 않는다 - 조롱해도 좋다$route
문제없이.
반면 기본 생성자에 vue-router를 여러 번 설치하면 문제가 발생합니다.가세하다$route
그리고.$router
읽기 전용 속성으로 지정합니다.그래서 향후 테스트에서 덮어쓰기가 불가능하죠
vue-test-utils를 사용하여 이를 실현하는 방법은 두 가지가 있습니다.
mocks 옵션을 사용한 vue-router 조롱
const $route = {
fullPath: 'full/path'
}
const wrapper = mount(ComponentWithRouter, {
mocks: {
$route
}
})
wrapper.vm.$route.fullPath // 'full/path'
createLocalVue를 사용하여 Vue 라우터를 안전하게 설치할 수도 있습니다.
createLocalVue를 사용한 테스트에서 vue-router를 안전하게 설치
const localVue = createLocalVue()
localVue.use(VueRouter)
const routes = [
{
path: '/',
component: Component
}
]
const router = new VueRouter({
routes
})
const wrapper = mount(ComponentWithRouter, { localVue, router })
expect(wrapper.vm.$route).to.be.an('object')
조롱하지 않는 것이 좋다vue-router
컴포넌트를 렌더링하기 위해 사용하는 것이 아니라 올바르게 동작하는 라우터를 얻을 수 있습니다.예:
import Vue from 'vue'
import VueRouter from 'vue-router'
import totest from 'src/components/totest'
describe('totest.vue', () => {
it('should totest renders stuff', done => {
Vue.use(VueRouter)
const router = new VueRouter({routes: [
{path: '/totest/:id', name: 'totest', component: totest},
{path: '/wherever', name: 'another_component', component: {render: h => '-'}},
]})
const vm = new Vue({
el: document.createElement('div'),
router: router,
render: h => h('router-view')
})
router.push({name: 'totest', params: {id: 123}})
Vue.nextTick(() => {
console.log('html:', vm.$el)
expect(vm.$el.querySelector('h2').textContent).to.equal('Fred Bloggs')
done()
})
})
})
주의사항:
- vue의 런타임 전용 버전을 사용하고 있기 때문에
render: h => h('router-view')
. - 테스트만 하고 있습니다.
totest
컴포넌트. 단, 다른 컴포넌트가 참조되고 있는 경우에는 필요한 컴포넌트도 있습니다.totest
예:another_component
를 참조해 주세요. - 당신은 필요하다
nextTick
HTML을 보거나 테스트하기 전에 렌더링해야 합니다.
문제들 중 하나는 제가 찾은 대부분의 예들이 이전 버전의vue-router
이행 매뉴얼을 참조해 주십시오.예를 들어,router.go()
이젠 안 먹혀요
아무도 날 도와주지 않아 그래서 난 그걸 파고들었어vue-test-utils
매뉴얼에 기재되어 있는 것으로 판명되었습니다.그래서 Import를 하셔야 합니다.
import { shallowMount,createLocalVue } from '@vue/test-utils';
import router from '@/router.ts';
const localVue = createLocalVue();
샘플을 작성했습니다.vue
사례.테스트 중에는shallowMount
그 때문에,vue
응용 프로그램인스턴스 및 라우터
describe('Components', () => {
it('renders a comment form', () => {
const COMMENTFORM = shallowMount(CommentForm,{
localVue,
router
});
})
})
라우터를 쉽게 통과시켜 얕은 마운트에 연결할 수 있으며, 이 경우 오류가 발생하지 않습니다.사용하는 상점을 통과하려면:
import { shallowMount,createLocalVue } from '@vue/test-utils';
import router from '@/router.ts';
import store from '@/store.ts';
const localVue = createLocalVue();
그런 다음 가게를 통과합니다.
describe('Components', () => {
it('renders a comment form', () => {
const COMMENTFORM = shallowMount(CommentForm,{
localVue,
router,
store
});
})
})
이 솔루션은 다음 오류를 해결했습니다.
- 사용할 때 정의되지 않은 속성 '파라임'을 읽을 수 없습니다.
this.$route.params.id
- 알 수 없는 사용자 지정 요소
router-link
✔
찾은 가장 쉬운 방법은 localVue를 사용하는 것입니다.
import { createLocalVue, mount } from '@vue/test-utils';
import VueRouter from 'vue-router';
import Vuex from 'vuex';
import ComponentName from '@/components/ComponentName.vue';
// Add store file if any getters is accessed
import store from '@/store/store';
describe('File name', () => {
const localVue = createLocalVue();
localVue.use(VueRouter);
// Can also be replaced with route(router.js) file
const routes = [
{
path: '/path',
component: ComponentName,
name: 'Route name'
}
];
const router = new VueRouter({ routes });
// if needed
router.push({
name: 'Route name',
params: {}
});
const wrapper = mount(ComponentName, {
localVue,
router,
store
});
test('Method()', () => {
wrapper.vm.methodName();
expect(wrapper.vm.$route.path)
.toEqual(routes[0].path);
});
});
도움이 되었으면 좋겠어!!!
라우터를 「mock」할 필요는 없습니다.애플리케이션은 VueRouter를 글로벌 vue 범위에서 설정할 수 있지만 테스트에서 원하는 작업을 문제 없이 수행할 수 있습니다.
localVue 사용 현황 읽기VueRouter
: https://vue-test-utils.vuejs.org/guides/ #using-with-vue-displays.
나는 현재 우리의 메인 앱에서 복잡한 라우터를 끌어오고 있으며, 그것을 할 수 있다.jest.spyOn()
의 콜router.push()
에 경로를 할 수도 있습니다.shallowMount()
의 created()
회피책
// 일부 Vue Component.표시하다
<template>
... something
</template>
<script>
...
data () {
return {
authenticated: false
}
},
...
created () {
if(!this.authenticated && this.$route.path !== '/'){
this.$router.push('/')
}
}
</script>
// 일부 Vue Component.spec.js
import Vuex from 'vuex'
import VueRouter from 'vue-router'
import { shallowMount, createLocalVue } from '@vue/test-utils'
import SomeVueComponent from 'MyApp/components/someVueComponent'
import MyAppRouter from 'MyApp/router'
import MyAppCreateStore from 'MyApp/createStore'
import merge from 'lodash.merge'
function setVueUseValues (localVue) {
localVue.use(Vuex)
localVue.use(VueRouter)
// other things here like custom directives, etc
}
beforeEach(() => {
// reset your localVue reference before each test if you need something reset like a custom directive, etc
localVue = createLocalVue()
setVueUseValues(localVue)
})
let localVue = createLocalVue()
setVueUseValues(localVue)
test('my app does not react to path because its default is "/"', () => {
const options = {
localVue,
router: MyAppRouter,
store: MyAppCreateStore()
}
const routerPushSpy = jest.spyOn(options.router, 'push')
const wrapper = shallowMount(SomeVueComponent, options)
expect(routerPushSpy).toHaveBeenCalledTimes(0)
})
test('my app reacts to path because its not "/" and were not authenticated', () => {
const options = {
localVue,
router: MyAppRouter,
store: MyAppCreateStore()
}
const routerPushSpy = jest.spyOn(options.router, 'push')
options.router.push('/nothomepath')
expect(routerPushSpy).toHaveBeenCalledWith('/nothomepath') // <- SomeVueComponent created hook will have $route === '/nothomepath' as well as fullPath
const wrapper = shallowMount(SomeVueComponent, options)
expect(routerPushSpy).toHaveBeenCalledWith('/') // <- works
})
은 제가 '하다'는 한 입니다.$route
" " " 전에 되었습니다.SomeVueComponent.vue
작성/마운트 됩니다.할 수 있고 컴포넌트 를 할 수 합니다.this.$router.push('/something')
할 수 wrapper.vm
삭제
let routerPushSpy = jest.spyOn(wrapper.vm.$router, 'push') // or before hooks, etc
에서 볼 때 이 있는 것 .vm.$route
되어 있지 않기 에 위의 는 다른 방법이입니다.다른 방법은 없습니다.$route
는 VueRouter에 전용 때문입니다.$route
vue-test-syslogs 문서 https://vue-test-utils.vuejs.org/guides/ #syslogs-route-and-syslogs에서 다음 절차를 수행합니다.
import { shallowMount } from '@vue/test-utils'
const $route = {
path: '/some/path'
}
const wrapper = shallowMount(Component, {
mocks: {
$route
}
})
wrapper.vm.$route.path // /some/path
이 문제의 재현에 관심이 있는 경우는, https://github.com/vuejs/vue-test-utils/issues/1136 를 참조해 주세요.
@SCOLvin의 답변에 대해 모두 칭찬합니다.이 시나리오에서는 라우터 링크가 있는 컴포넌트를 사용하여
ERROR: '[Vue warn]: Error in render function: (found in <RouterLink>)'
Vue는 라우터와 함께 제공되지 않았기 때문에 유닛 테스트 중@SCOLvin answer를 사용하여 vue-cli가 원래 제공한 테스트를 다시 작성합니다.
describe('Hello.vue', () =>
{
it('should render correct contents', () =>
{
const Constructor = Vue.extend(Hello);
const vm = new Constructor().$mount();
expect(vm.$el.querySelector('.hello h1').textContent)
.to.equal('Welcome to Your Vue.js App');
});
로.
describe('Hello.vue', () =>
{
it('should render correct contents', () =>
{
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{ path: '/', name: 'Hello', component: Hello },
],
});
const vm = new Vue({
el: document.createElement('div'),
/* eslint-disable object-shorthand */
router: router,
render: h => h('router-view'),
});
expect(vm.$el.querySelector('.hello h1').textContent)
.to.equal('Welcome to Your Vue.js App');
});
});
파라미터를 뷰에 전달할 필요가 없기 때문에 컴포넌트를 디폴트 렌더로서 심플하게 할 수 있어 푸시할 필요도 nextTick을 기다릴 필요도 없습니다.다른 사람이요!
왜 모든 답이 이렇게 복잡하지?다음 작업을 수행할 수 있습니다.
...
wrapper = mount(HappyComponent, {
mocks: {
$route: {fullPath: ''}
},
})
...
@SCOLvin의 훌륭한 답변에 덧붙여, Avoriaz를 사용한 이 작업의 예를 다음에 나타냅니다.
import { mount } from 'avoriaz'
import Vue from 'vue'
import VueRouter from 'vue-router'
import router from '@/router'
import HappyComponent from '@/components/HappyComponent'
Vue.use(VueRouter)
describe('HappyComponent.vue', () => {
it('renders router links', () => {
wrapper = mount(HappyComponent, {router})
// Write your test
})
})
이것은 vue-test-utils에도 유효하다고 생각합니다.
vue-test-utils를 사용한 이 예에서는 라우터와 스토어를 모두 조롱하고 있습니다.
import ArticleDetails from '@/components/ArticleDetails'
import { mount } from 'vue-test-utils'
import router from '@/router'
describe('ArticleDetails.vue', () => {
it('should display post details', () => {
const POST_MESSAGE = 'Header of our content!'
const EXAMPLE_POST = {
title: 'Title',
date: '6 May 2016',
content: `# ${POST_MESSAGE}`
}
const wrapper = mount(ArticleDetails, {
router,
mocks: {
$store: {
getters: {
getPostById () {
return EXAMPLE_POST
}
}
}
}
})
expect(wrapper.vm.$el.querySelector('h1.post-title').textContent.trim()).to.equal(EXAMPLE_POST.title)
expect(wrapper.vm.$el.querySelector('time').textContent.trim()).to.equal(EXAMPLE_POST.date)
expect(wrapper.vm.$el.querySelector('.post-content').innerHTML.trim()).to.equal(
`<h1>${POST_MESSAGE}</h1>`
)
})
})
it('renders $router.name', () => {
const scopedVue = Vue.extend();
const mockRoute = {
name: 'abc'
};
scopedVue.prototype.$route = mockRoute;
const Constructor = scopedVue.extend(Component);
const vm = new Constructor().$mount();
expect(vm.$el.textContent).to.equal('abc');
});
VM을 조롱할 수 있습니다.VM을 설정하여 $140._routerRoot._개요
예를들면
var Constructor = Vue.extend(Your_Component)
var vm = new Constructor().$mount()
var your_mock_router = {hello:'there'}
vm.$router = your_mock_router //An error 'setting a property that has only a getter'
vm._routerRoot._router = your_mock_router //Wow, it works!
https://github.com/vuejs/vue-router/blob/dev/dist/vue-router.js#L558 에서 소스코드를 재확인할 수 있습니다.
내가 찾은 가장 쉬운 방법은 $route를 조롱하는 거야.
it('renders $router.name', () => {
const $route = {
name: 'test name - avoriaz'
}
const wrapper = shallow(Component, {
mocks: {
$route
}
})
expect(wrapper.text()).to.equal($route.name)
})
언급URL : https://stackoverflow.com/questions/41458736/how-to-write-test-that-mocks-the-route-object-in-vue-components
'it-source' 카테고리의 다른 글
DIV의 내용을 인쇄합니다. (0) | 2022.10.21 |
---|---|
Unix 타임스탬프 형식으로 현재 GMT 시간을 얻는 가장 쉬운 방법은 무엇입니까? (0) | 2022.10.21 |
Rasberry Pi2에서 실행되는 MariaDB의 테이블에 CSV를 로드하려면 어떻게 해야 합니까? (0) | 2022.10.21 |
Class.forName("oracle.jdbc.driver")의 실제 용도는 무엇입니까?Oracle Driver")를 데이터베이스에 연결하는 동안? (0) | 2022.10.21 |
MySQL 기본 키 업데이트 중 (1) | 2022.10.21 |