[TOC]
  • 使用了全局组件
    • a-button
    • a-menu
    • … …
  • 使用了外部的模块
    • useStore
    • useRouter
    • message ```vue

<a name="IlGmA"></a>
# mock 全局组件
```typescript
import { shallowMount, VueWrapper } from '@vue/test-utils'
import UserProfile from '@/components/UserProfile.vue'

// 模拟第三方库 vue-router
jest.mock('vue-router')
// 模拟第三方库 ant-design-vue
jest.mock('ant-design-vue')
// 模拟第三方库 vuex
jest.mock('vuex')

let wrapper: VueWrapper<any>

describe('UserProfile.Vue', () => {
  beforeEach(() => {
    wrapper = shallowMount(UserProfile, {
      props: { user: { isLogin: false, userName: '' } },
    })
  })
  afterAll(() => {})
  it('should render login buttom when login is false', async () => {
    console.log(wrapper.html())
  })

  it('should render username when login is true', async () => {
    console.log(wrapper.html())
  })
})

报错: Failed to resolve component: a-dropdown-button,因为需要定义全局组件。
image.png

import { shallowMount, VueWrapper } from '@vue/test-utils'
import UserProfile from '@/components/UserProfile.vue'

// 模拟第三方库 vue-router
jest.mock('vue-router')
// 模拟第三方库 ant-design-vue
jest.mock('ant-design-vue')
// 模拟第三方库 vuex
jest.mock('vuex')

const commonComponent = {
  template: '<div><slot></slot></div>',
}

//虚拟div 代替第三方组件
const globalComponents = {
  'a-button': commonComponent,
  'a-dropdown-button': commonComponent,
  'a-menu': commonComponent,
  'a-menu-item': commonComponent,
}
let wrapper: VueWrapper<any>

    describe('UserProfile.Vue', () => {
      beforeEach(() => {
        wrapper = shallowMount(UserProfile, {
          props: { user: { user: { isLogin: false, userName: '' } } },
          //定义全局组件
          global: {
            components: globalComponents,
            // 如果是在文件中注册的组件,需要使用 stubs
            stubs: globalComponents,
          },
        })
      })
      afterAll(() => {})
      it('should render login buttom when login is false', () => {
        console.log(wrapper.html())
        expect(wrapper.get('div').text()).toBe('登录')
      })

      it('should render username when login is true', async () => {
        //修改组件内部传入的属性值  需改了dom,记得加aysnc,await
        await wrapper.setProps({
          user: { user: { isLogin: true, userName: 'haha' } },
        })
        console.log(wrapper.html())
      })
    })

报错: [Vue warn]: Failed to resolve component: a-menu-item,因为
a-menu-item内部有slot
image.png
image.png

...

const commonComponent = {
  template: '<div><slot></slot></div>',
}

const dropdownComponent = {
  template: '<div><slot></slot><slot name="overlay"></slot></div>',
}

//虚拟div 代替第三方组件
const globalComponents = {
  'a-button': commonComponent,
  'a-dropdown-button': dropdownComponent,
  'a-menu': commonComponent,
  'a-menu-item': commonComponent,
}
let wrapper: VueWrapper<any>

describe('UserProfile.Vue', () => {
 ...
  it('should render username when login is true', async () => {
    //修改组件内部传入的属性值  需改了dom,记得加aysnc,await
    const userName = 'haha'
    await wrapper.setProps({
      user: { user: { isLogin: true, userName } },
    })
    console.log(wrapper.html())
    expect(wrapper.get('.user-profile-component span').text()).toBe(userName)
    expect(wrapper.find('.user-profile-dropdown').exists()).toBeTruthy()
  })
})

image.png

模拟第三方库