Jest.js 带有:to属性的单元测试VueRouter

kb5ga3dv  于 2023-03-06  发布在  Jest
关注(0)|答案(1)|浏览(221)

我有一个简单的测试用例(Vue 2、Vuetify 2、vue-router、jest、vue-test-utils),其中单击了一个Vuetify v-btn组件并转到一个新的路由

<v-btn id="create-plan-btn" :to="{ 'name': 'newPlan', query: { dept: 216001 }}">Create plan</v-btn>

但是,我不知道如何注册一个捕获**:to**属性动作的click方法。

describe('when "Create Plan button is clicked', () => {
  const localVue = createLocalVue()
  let vuetify

  beforeEach(() => {
    vuetify = new Vuetify()
  })

  const $route = { path: '/student/index', name: 'studentLanding' }

  const mockRouter = {
    to: jest.fn(),
    push: jest.fn()
  }
  const wrapper = shallowMount(StudentLanding, {
    localVue,
    stubs: {'router-link': RouterLinkStub},
    mocks: {
      $route: $route,
      $router: mockRouter
    }
  })

  it('triggers Vue router call to the new plan page', async () => {
    const button = wrapper.find('#create-plan-btn')
    expect(button.exists()).toBe(true)
    expect(mockRouter.push).toHaveBeenCalledTimes(0)
    button.vm.$emit('click') // Vuetify buttons need "vm.$emit" to be triggered, not "trigger()" like a normal HTML button would
    await wrapper.vm.$nextTick()
    expect(mockRouter.push).toHaveBeenCalledTimes(1)
    expect(mockRouter.push).toHaveBeenCalledWith({ name: 'newPlan', query: { dept: 216001 }})
  })
})

●点击“创建计划"按钮时›触发Vue路由器调用新计划页面

expect(jest.fn()).toHaveBeenCalledTimes(expected)

Expected number of calls: 1
Received number of calls: 0

请注意,将push更改为to对上面的代码也没有任何影响。
但是,如果我将我的改为使用@click回调,测试*****会成功:

// Test succeeds with this code
<v-btn id="create-plan-btn" @click="redirect">Create plan</v-btn>

redirect () {
   this.$router.push({ name: 'newPlan', query: { dept: 216001 }});
}

有没有办法修改这个测试,让:to prop在点击时被捕获?我试着至少确保:to prop的内容在测试中可见,但是我只得到**[object Object]**的返回:

expect(button.attributes('to').toString()).toEqual({ name: 'newPlan', query: { dept: 216001 }})

预期:{“名称”:“新计划”,“查询”:{“部门”:216001}}接收日期:“[对象对象]”

ua4mk5z4

ua4mk5z41#

我相当肯定这与您的emit有关,而不是您实际单击它的事实。
我建议你稍微改变一下测试:

it('triggers Vue router call to the new plan page', async () => {
    const button = wrapper.find('#create-plan-btn')
    expect(button.exists()).toBeTruthy()
    expect(mockRouter.push).toHaveBeenCalledTimes(0)
    await button.trigger('click')
    await wrapper.vm.$nextTick() // This could probably be omitted since we're awaiting the click above
    expect(mockRouter.push).toHaveBeenCalledTimes(1)
    expect(mockRouter.push).toHaveBeenCalledWith({ name: 'newPlan', query: { dept: 216001 }})
  })

另外,测试按钮属性的目的是什么?既然你已经在那里写了它们,它们在任何方面都不是动态的,那么它们就是动态的。但是,如果你真的想测试它,我认为问题出在toString()函数上,你可以尝试用JSON字符串化它:
expect(JSON.stringify(button.attributes('to'))).toEqual({ name: 'newPlan', query: { dept: 216001 }})
虽然它也应该是可能的只是做:
expect(button.attributes('to')).toStrictEqual({ name: 'newPlan', query: { dept: 216001 }})
我真的不知道你说Vuetify按钮需要使用$emit是什么意思,我一直都是这样测试Vuetify按钮的。
我还建议做一个简单的更改,不要使用ID进行测试,而是创建一个属性data-testid="router-button",您可以使用该属性命名并查找组件:
const button = wrapper.find('[data-testid="router-button"]')
这清楚地表明,它只用于测试,没有其他用途。

相关问题