[单元测试]vue2.x迁移vue3.x

vue已经从对应的vue2.x迁移为vue3.x,可以参考官方迁移文档

遇到的其它问题,记录一下,方便以后迁移遇到问题时查找

环境

"@vue/cli-service": "~5.0.8",
"@vue/vue3-jest": "^27.0.0-alpha.3",
"jest": "^27.5.1",
"ts-jest": "^27.1.5",

迁移问题

vue文件中使用了全局注册组件

三方组件不是在vue文件中注册的,是全局注册的,所以mount该vue组件文件的时候,提示无法识别三方组件

那么三方组件如何注册,使用过在选项中直接添加components选项,与shallow平级,无效

然后,找到以下注册全局组件的方式

let wrapper = mount(NoFound, {
    shallow: true,//渲染子组件,但是子组件内部就不会继续渲染了,哪怕设置了
    global: {//组件在全局注册时,测试时的添加方法
        components: globalComponents,
        stubs:{},
        // renderStubDefaultSlot
    }
});

渲染slot

在测试的vue组件文件中,存在的三方组件中存在slot,默认是不渲染的,如果我们希望所有的slot都被渲染出来需要以下设置

import { config } from '@vue/test-utils'
config.global.renderStubDefaultSlot = true

注册全局组件与渲染slot示例

场景:
vue文件







测试文件

import { mount, config } from "@vue/test-utils";
import NoFound from "@/src/components/no-found.vue";
import { Result, Button } from 'ant-design-vue';

// 模拟组件
const mockComponent = {
    template: `
`
, }; // 全局组件列表 const globalComponents = { 'a-button': Button, 'a-result': Result, 'router-link': mockComponent, }; beforeAll(() => { config.global.renderStubDefaultSlot = true }) let wrapper; let container; describe("NoFound component:", () => { beforeEach(() => { wrapper = mount(NoFound, { shallow: true, global: { components: globalComponents } }); container = mount(NoFound, { global: { components: globalComponents } }); }) it("NoFound child component slot is render,contain 'Back Home'", () => { //wrapper不可以 expect(container.getComponent(mockComponent).html()).toContain("Back Home"); }); it("container contain result component", () => { expect(container.findComponent(Result).exists()).toBeTruthy(); }); it("wrapper contain result component ", () => { expect(wrapper.findComponent(Result).exists()).toBeTruthy(); }); it("NoFound child component Result default 404 is render", () => { expect(container.getComponent(Result).html()).toContain("Sorry, the page you visited does not exist"); }); it("NoFound child component Result pass prop data to it", () => { const temp = mount(NoFound, { props: { status: "500", title: 500, subTitle: 'Server error' }, shallow: true, global: { components: globalComponents } }); expect(temp.getComponent(Result).html()).toContain("Server error"); }); afterEach(() => { wrapper.unmount() container.unmount();//销毁组件实例 }) }); afterAll(() => { config.global.renderStubDefaultSlot = false })

以上代码的测试运行:

it("NoFound child component slot is render,contain 'Back Home'", () => {
    //"wrapper 不可以"
    expect(container.getComponent(mockComponent).html()).toContain("Back Home");
});

如果测试的是wrapper则提示以下内容,断言错误,感觉shallow: true参数阻止了内部参数的渲染,所以内部的slot更加无法渲染,所以无法获取"Back Home"

判断组件是否存在

//正确
expect(wrapper.findComponent(NoFound).exists()).toBeTruthy()
//错误
expect(wrapper.findComponent(NoFound).exists()).toBe(true)

TypeError: window.matchMedia is not a function

这个是在使用了vue3的写法中报错了,包括vue3 语法糖的写法与defineComponent的setup组合式API的写法,网上有说是因为babel-jest,jest,与ts-jest版本不一致导致,本人更新后发现没有任何作用

在尝试过后发现是无效的,无意间更改了挂载的方法

wrapper = mount(NoFound, {
    global: {
        components: globalComponents
    }
});

wrapper = shallowMount(NoFound, {
    global: {
        components: globalComponents
    }
});

我在官网看说是设置了shallow: true mount 方法与shallowMount等效的,所以设置了 shallow: true的mount也不会报错TypeError: window.matchMedia is not a function。如果有报错,请查看是不是存在没有设置该属性的 mount 方法

所以设置了shallow为true,所有断言渲染后属性的都不成立,因为内部包括自身的组件是没有渲染的


在以后的版本之中不知是否修复,但是碍于使用的是@vue/cli-service,目前最高版本是5.0.8,所以导致 "@vue/vue3-jest": "^27.0.0-alpha.3"只能使用该版本,所以对应的jest等版本也不能升级

组件的渲染问题只能等以后可以升级或者改变脚手架后再看了

你可能感兴趣的:(VueJs,vue.js)