为了账号安全,请及时绑定邮箱和手机立即绑定

【九月打卡】第2天 测试高级技巧

课程名称web前端架构师

课程章节:第11周 第四章

主讲老师:张轩

课程内容:掌握测试的一些高级用法,全局组件的测试、vue-router 和 store 的测试

测试中 mock 全局组件的实现

开发过程中经常会使用到一些第三方的组件,比如 element-plus 和 antd-vue 等

测试过程中无需关心组件内部的实现,组件内部的测试放在组件内部去测试

模拟组件的实现

const mockComponent = {
  template: '<div><slot></slot></div>'
}
// 根据页面上使用的全局组件,模拟全局组件
const globalComponents = {
  'el-button': mockComponent,
  'el-dropdown-menu': mockComponent,
  'el-dropdown-item': mockComponent
}

挂载时将全局组件注册到全局

let wrapper: VueWrapper
beforeAll(() => {
  wrapper = mount(UserProfile, {
    global: {
      components: globalComponents
    }
  })
})

下面就可以测试了

  it('user profile', async () => {
    expect(wrapper.html()).toContain('用户xxx')
  })

当配到组件中使用插槽时,上面代码就会出现问题,这时我们需要对插槽的组件做特殊处理。例如下面代码

<el-dropdown
  split-button
  type="primary"
  v-if="userStore.isLogin"
>
  用户{{ userStore.user }}
  <template #dropdown>
    <el-dropdown-menu>
      <el-dropdown-item
        class="setting"
        @click="gotoSetting"
      >
        个人设置
      </el-dropdown-item>
      <el-dropdown-item
        @click="logout"
        class="logout"
      >
        退出登录
      </el-dropdown-item>
    </el-dropdown-menu>
  </template>
</el-dropdown>

下面做特殊处理

{
  'el-dropdown': {
    template: '<div><slot></slot><slot name="dropdown"></slot></div>'
  }
}

模拟第三方库的实现

当我们在组件中调用 ElMessage.success 方法时,我们判断是否调用过ElMessage.success

还是可以通过模拟组件内部方法的实现来测试

vi.mock('element-plus', () => ({
  ElMessage: {
    success: vi.fn()
  }
}))
 expect(ElMessage.success).toHaveBeenCalled()

组件中使用 pinia 的测试

课程总使用的是 vuex ,我在可以使用了 pinia 完成了同样的测试

处理过程也比较简单

import useUserStore from '@/store/user'
...
it('user logout', async () => {
  const store = useUserStore()
  await wrapper.get('.logout').trigger('click')
  expect(ElMessage.success).toHaveBeenCalled()
  expect(store.isLogin).toBeFalsy()
  expect(wrapper.get('div').text()).toBe('登录')
})

组件中 vue-router 的测试

同样也可以通过模拟内部的实现来进行测试

模拟 router.push 的实现

const mockRoutes:string[] = []
vi.mock('vue-router', () => ({
  useRouter: () => ({
    push: (url: string) => mockRoutes.push(url)
  })
}))
it.only('go to setting', async () => {
  await wrapper.get('.setting').trigger('click')
  expect(mockRoutes).toEqual(['/setting'])
})

在 使用vitest 运行时,发现怎么允许都不正确,mockRoutes始终都时空数组,在这里卡了好长时间,没办法上 vitest github 的 issue 上搜索了下,找到了解决办法

需要在 vite 配置文件中增加下面

{
  resolve: {
    conditions: process.env.VITEST ? ['node'] : []
  }
}

再次运行测试文件,正常运行图片描述

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消