【问题标题】:Write unit test for a method in a component in Vue with Jest使用 Jest 在 Vue 中为组件中的方法编写单元测试
【发布时间】: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)
   })
})

【问题讨论】:

    标签: vue.js unit-testing jestjs


    【解决方案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)
      })
    })
    

    【讨论】:

      猜你喜欢
      • 2020-06-25
      • 2019-01-02
      • 2020-06-12
      • 1970-01-01
      • 2017-04-06
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多