使用 Jest 在 Vue 中为组件中的方法编写单元测试
Posted
技术标签:
【中文标题】使用 Jest 在 Vue 中为组件中的方法编写单元测试【英文标题】:Write unit test for a method in a component in Vue with Jest 【发布时间】:2021-09-05 17:57:36 【问题描述】:我开始使用 Jest Vue 进行单元测试。我想测试一个 Vue 组件中的现有方法,我写了一个测试但它没有通过。而且我不知道如何在测试中模拟和调用该方法。
如何编写一个好的单元测试,以传递 'goPage()' 方法的功能?
我的方法是:
goPage(id, name, categoryId)
this.headerSearchInput = name
this.$router.push(
path: '/categories/' + categoryId + '/courses/' + id,
query: query: this.headerSearchInput ,
)
我的测试是:
import shallowMount, createLocalVue from '@vue/test-utils'
import HeaderSearch from '../../components/header/HeaderSearch.vue'
const localVue = createLocalVue()
localVue.use(VueRouter)
const router = new VueRouter()
describe('Header search component', () =>
const mockRoute =
path: '/categories/' + 2 + '/courses/' + 4,
query:
query: searchedText,
,
const mockRouter =
push: jest.fn(),
const wrapper = shallowMount(HeaderSearch,
router,
localVue,
stubs:
NuxtLink: true,
,
global:
mocks:
$route: mockRoute,
$router: mockRouter,
,
,
)
test('redirect to course page, goPage', async () =>
const courseId = 4
const courseTitle = 'Inbound Marketing'
const categoryId = 2
const mockedFunction = jest.fn()
wrapper.vm.goPage(courseId, courseTitle, categoryId)
await wrapper.setData(
headerSearchInput: courseTitle,
)
const expectedRouter =
path: '/categories/3/courses/4',
query: query: wrapper.vm.headerSearchInput ,
expect(mockedFunction).toBeCalledWith(courseId, courseTitle, categoryId)
expect(wrapper.vm.$router.path).toEqual(expectedRouter.path)
)
)
【问题讨论】:
【参考方案1】:当您测试路由时,您应该只使用模拟而不在您的 local Vue
实例上安装 VueRouter
。正如官方documentation 所说:
在 localVue 上安装 Vue 路由器还会将 $route 和 $router 作为只读属性添加到 localVue。这意味着在使用安装了 Vue Router 的 localVue 安装组件时,您不能使用 mocks 选项覆盖 $route 和 $router。
所以你需要在shallowMount
调用中获取localVue
的reed,只留下$router
嘲笑:
然后在测试中,您只需调用您的 goPage
方法并检查 $router.push()
是否使用特定参数调用。 不检查 $route.path
是否已更改,将其留给端到端测试。
let wrapper
describe('HelloWorld.vue', () =>
beforeEach(() =>
wrapper = shallowMount(HelloWorld,
global: mocks: $router: push: jest.fn()
)
)
test('redirect to course page, goPage', async () =>
const courseId = 4
const courseTitle = 'Inbound Marketing'
const categoryId = 2
const expectedRouter =
path: '/categories/' + categoryId + '/courses/' + courseId,
query: query: 'Inbound Marketing'
wrapper.vm.goPage(courseId, courseTitle, categoryId)
expect(wrapper.vm.$router.push).toBeCalledWith(expectedRouter)
)
)
【讨论】:
我像你说的那样写了测试,但是它抛出了Cannot read property 'push' of undefined
错误。我该如何解决? @爱德华多
请提供带有包装器实例化的测试代码。
代码很长,所以我用2个cmets来写。 const wrapper = shallowMount(HeaderSearch, stubs: NuxtLink: true, , global: mocks: $router: push: jest.fn(), , , , )
test('redirect to course page, goPage', async () => const courseId = 4 const courseTitle = 'Inbound Marketing' const categoryId = 2 const expectedRouter = path: '/categories/' + categoryId + '/courses/' + courseId, query: query: wrapper.vm.headerSearchInput , wrapper.vm.goPage(courseId, courseTitle, categoryId) await wrapper.setData( headerSearchInput: courseTitle, ) expect(wrapper.vm.$router.push).toBeCalledWith(expectedRouter) )
我已经更新了我的答案,请检查一下。【参考方案2】:
我解决了我的问题,如下所示:
let wrapper
describe('HeaderSearch', () =>
const $route =
path: '/categories/2/courses/4',
const $router =
push: jest.fn(),
beforeEach(() =>
wrapper = shallowMount(HeaderSearch,
mocks:
$route,
$router,
,
)
)
test('go to each course page', () =>
const courseId = 4
const categoryId = 2
const courseTitle = 'Inbound Marketing'
wrapper.vm.goPage(courseId, courseTitle, categoryId)
const expectedRouter =
path: '/categories/' + categoryId + '/courses/' + courseId,
query: query: courseTitle ,
expect(wrapper.vm.$router.push).toBeCalledWith(expectedRouter)
)
)
【讨论】:
以上是关于使用 Jest 在 Vue 中为组件中的方法编写单元测试的主要内容,如果未能解决你的问题,请参考以下文章
使用 <script setup> 时无法使用 Jest 访问 Vue 单文件组件中的方法