简体   繁体   English

使用JEST对Vue.js路由器进行单元测试-如何模拟页面?

[英]Unit Testing a Vue.js Router with JEST - How to mock pages?

I am trying to unit test my router routes and, following various examples, I have come up with some test cases. 我正在尝试对路由器的路由进行单元测试,并在各种示例之后,提出了一些测试用例。 I have split my router out into separate modules for routes, guards and the router itself to make it easier to test, so I'm effectively only testing the route definitions here. 我将路由器分为用于路由,防护和路由器本身的单独模块,以使其更易于测试,因此,我实际上仅在此处测试路由定义。 Here's a sample of my routes... 这是我的路线的一个示例...

import Guards from './guards'
import Views from '@/views'

export default [
    {
        path: '/',
        props: true,
        components: {
            default: Views.Pages.Wizard,
            header: Views.Headers.Wizard
        },
        children: [
            {
                path: '',
                name: 'Welcome',
                component: Views.Welcome
            },
            {
                path: 'verify-guest',
                name: 'ReCaptcha',
                component: Views.ReCaptcha
            }
        ]
    },
    {
        path: '/:postcode/:id/:address',
        props: true,
        components: {
            default: Views.Pages.Main,
            header: Views.Headers.Main
        },
        children: [
            {
                path: '',
                name: 'MyHome',
                props: true,
                component: Views.MyHome,
                beforeEnter: Guards.requireSelectedProperty
            },
            {
                path: 'improvements',
                name: 'Improvements',
                props: true,
                component: Views.Improvements,
                beforeEnter: Guards.requireSelectedProperty
            }
        ]
    }
]

I have written some tests and the tests to load the lading page (welcome) pass but everything else seems to fail that I try - It's as if the router only ever loads the landing page. 我已经编写了一些测试,并且测试加载了载入页面(欢迎)通过,但是我尝试的所有其他操作似乎都失败了-好像路由器只载入了登陆页面。

The tests look like this... 测试看起来像这样...

import Helper from '../../test-helper'
import { mount, createLocalVue } from '@vue/test-utils'

import VueRouter from 'vue-router'

import App from '../../templates/app-bare.vue'
import Views from '@/views'

import routes from '@/router/routes.js'
import MockGuards from '@/router/guards.js'

jest.mock('@/router/guards.js', () => ({
    requireUser: jest.fn(),
    requireFullUser: jest.fn(),
    requireCurrentProject: jest.fn(),
    requireSelectedProperty: jest.fn()
}))

jest.mock('@/views/headers/main.vue', () => ({
    name: 'MainHeader',
    render: h => h('div')
}))

jest.mock('@/views/headers/wizard.vue', () => ({
    name: 'WizardHeader',
    render: h => h('div')
}))

jest.mock('@/views/welcome.vue', () => ({
    name: 'Welcome',
    render: h => h('span')
}))

jest.mock('@/views/my-home.vue', () => ({
    name: 'MyHome',
    render: h => h('section')
}))

const localVue = createLocalVue()
localVue.use(VueRouter)

describe('router', () => {
    let router
    let wrapper

    beforeEach(() => {
        router = new VueRouter({ base: '/', routes })
        wrapper = mount(App, {
            localVue,
            router,
            mocks: Helper.vueMockPlugins()
        })
    })

    describe('can load the landing page', () => {

        it('via a path', () => {
            router.push('/')
            expect(wrapper.find(Views.Welcome).exists()).toBeTruthy()
            expect(wrapper.find(Views.Headers.Wizard).exists()).toBeTruthy()
        })

        it('via a name', () => {
            router.push({ name: 'Welcome' })
            expect(wrapper.find(Views.Welcome).exists()).toBeTruthy()
            expect(wrapper.find(Views.Headers.Wizard).exists()).toBeTruthy()
        })
    })

    /*

    None of these work - can only ever make the router render 'Welcome'

    describe('can load the root of my home', () => {

        it('via a path', () => {
            router.push('/KT18%207LJ/1/3%20The%20Crescent/')
            console.log(wrapper.html())
            expect(wrapper.find(Views.MyHome).exists()).toBeTruthy()
            expect(wrapper.find(Views.Headers.Main).exists()).toBeTruthy()
        })

        it('via a name with parameters', () => {
            router.push({ name: 'MyHome', params: {
                id: 1,
                postcode: 'KT18 7LJ',
                address: '3 The Crescent'
            } })
            console.log(wrapper.html())
            expect(wrapper.find(Views.MyHome).exists()).toBeTruthy()
            expect(wrapper.find(Views.Headers.Main).exists()).toBeTruthy()
        })
    })

    */
})

Any ideas? 有任何想法吗? I'm very new to JEST and unit testing with Vue at all - I've much more prior experience with Jasmine and Mocha / Chai / Sinon. 我对JEST和Vue进行单元测试非常陌生-我在Jasmine和Mocha / Chai / Sinon方面拥有更多的经验。

I fixed this myself in the end. 最后我自己解决了这个问题。 The answer was not with the pages but the mocking of my guards (simple when you see it). 答案不在于页面,而是嘲笑我的警卫(当您看到它时很简单)。 Instead of this... 代替这个...

jest.mock('@/router/guards.js', () => ({
    requireUser: jest.fn(),
    requireFullUser: jest.fn(),
    requireCurrentProject: jest.fn(),
    requireSelectedProperty: jest.fn()
}))

I needed to replace them with this... 我需要用这个代替它们...

jest.mock('@/router/guards.js', () => ({
    requireUser: jest.fn((_to, _from, next) => {
        next()
    }),
    requireCurrentProject: jest.fn((_to, _from, next) => {
        next()
    }),
    requireFullUser: jest.fn((_to, _from, next) => {
        next()
    }),
    requireSelectedProperty: jest.fn((_to, _from, next) => {
        next()
    })
}))

As, without a 'next' function to call the mock guard is hit and then the route doesn't execute beyond that point. 因为,如果没有“下一步”功能来调用模拟后卫,那么该路线将无法执行。 The 'next' call is required to actually pass through the rendering of the route. 实际上需要通过“下一个”调用来传递路径。

'Welcome' appears to render all of the time as it's the landing page and therefore the default return in the event that a guard fails. “ Welcome”似乎一直都是着陆页,因此在警卫队失败的情况下默认返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM