У меня есть компонент, который содержит инструкцию типа this.$route.fullPath
, как мне высмеять значение fullPath
объекта $route
, если я хочу проверить этот компонент?
Как написать тест, который издевается над объектом $route в компонентах vue
Ответ 1
Лучше не издеваться над 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()
, который теперь не работает.
Ответ 2
Я не согласен с лучшим ответом - вы можете ошибаться в $route
без каких-либо проблем.
С другой стороны, установка vue-router несколько раз на базовый конструктор вызовет проблемы. Он добавляет $route
и $router
качестве свойств только для чтения. Это делает невозможным перезаписать их в будущих тестах.
Есть два способа добиться этого с помощью vue-test-utils.
Mocking vue-router с опцией mocks
const $route = {
fullPath: 'full/path'
}
const wrapper = mount(ComponentWithRouter, {
mocks: {
$route
}
})
wrapper.vm.$route.fullPath // 'full/path'
Вы также можете безопасно установить Vue Router с помощью createLocalVue:
Установка vue-router безопасно в тестах с помощью createLocalVue
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')
Ответ 3
Все благодарности за @SColvin за его ответ; помогли найти ответ в моем сценарии, в котором у меня был компонент с маршрутизатор-ссылкой, которая бросала
ERROR: '[Vue warn]: Error in render function: (found in <RouterLink>)'
во время unit test, потому что Vue не поставлялся с маршрутизатором. Используя @SColvin ответ, чтобы переписать тест, первоначально поставляемый 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. HTH кто-то еще!
Ответ 4
Добавляя к большому ответу от @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.
Ответ 5
Взгляните на этот пример, используя 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>`
)
})
})
Ответ 6
Это то, что я делал по в этой статье:
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');
});
Ответ 7
Вы можете издеваться над vm. $ Router, установив vm._routerRoot._router
Например
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
Ответ 8
Самый простой способ, который я нашел, - высмеять $ route.
it('renders $router.name', () => {
const $route = {
name: 'test name - avoriaz'
}
const wrapper = shallow(Component, {
mocks: {
$route
}
})
expect(wrapper.text()).to.equal($route.name)
})
Ответ 9
Самый простой метод, который я нашел, - использовать localVue
import { createLocalVue, mount } from '@vue/test-utils'
import ComponentName from 'componentPath'
import Vuex from 'vuex'
import store from '@/store/store' //Add store file if any getters is accessed
import VueRouter from 'vue-router'
describe('File name', () => {
const localVue = createLocalVue()
localVue.use(VueRouter)
const routes = [ //Can also be rreplaced with route(router.js) file
{
path: '/path',
component: ComponentName,
name: 'Route name'
}
]
const router = new VueRouter({
routes
})
router.push({
name: 'Route name',
params: {}
}) //if needed
const wrapper = mount(ComponentName, {localVue, router, store })
beforeEach(function() {
});
it('Method()', () => {
wrapper.vm.methodName()
expect(wrapper.vm.$route.path).toBe(routes[0].path)
});
});
Надеюсь, поможет!!!
Ответ 10
Никакой ответ не помог мне, поэтому я копаюсь в документации vue-test-utils
и нашел себе рабочий ответ, поэтому вам нужно импортировать.
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
✔