使用 Web 组件测试 vue

Testing vue with a web component

我的应用程序正在使用 astrouxds 网络组件,我在测试中收到一条警告,我想修复。我也不确定如何断言 Web 组件中的值。

  console.error node_modules/vue/dist/vue.runtime.common.dev.js:621
    [Vue warn]: Unknown custom element: <rux-toggle> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
    
    found in
    
    ---> <App>
           <Root>

我已经设置了一个示例应用程序 here。以rux-toggle为例。

该应用程序在 .vue 文件中有一个简单的模板和脚本。

<template>
  <div id="app">
    <rux-toggle
        id="app-toggle"
        :checked="toggle"
        @click.prevent="toggle = !toggle"></rux-toggle> {{ toggle }}
  </div>
</template>

<script>

export default {
  name: 'App',
  computed: {
    toggle: {
      get() {
        return this.$store.state.toggle
      },
      set(value) {
        this.$store.commit('setToggle', value)
      }
    }
  }
}
</script>

该测试使用 mount 创建包装器并测试是否检查了 Web 组件。

import Vuex from 'vuex';
import {createLocalVue, mount} from '@vue/test-utils';
import storeConfig from '@/store'
import App from '@/App'

describe("App", () => {
  let localVue;
  let store;
  let wrapper;

  beforeEach(() => {
    localVue = createLocalVue();
    localVue.use(Vuex);
    store = new Vuex.Store(storeConfig);
    wrapper = mount(App, {store, localVue});
  });

  it("test toggle default", () => {
    const result = wrapper.find('#app-toggle').checked;
    expect(result).toEqual(true);
  })
})

测试失败:

Error: expect(received).toEqual(expected) // deep equality

Expected: true
Received: undefined

我不确定如何获取 Web 组件的 checked 值以正确执行断言。

我尝试过的东西

  1. 从 shallowMount 切换到 mount
  2. 使用 Vue.component(rux-toggle, RuxToggle)
  3. 全局注册
  4. 已将 Vue.config.productionTip = false 添加到 jest 设置

rux-toggle 组件仅在 main.js 中注册,导致您观察到 warnings/errors。

关于您的尝试:

  1. Switched from shallowMount to mount

自定义元素必须由您自己的代码显式注册,mount 不会为您做那件事。

  1. Register globally using Vue.component(rux-toggle, RuxToggle)

RuxToggle 来自 @astrouxds/rux-toggleLitElement, which does not meet the requirements of a Vue component definition that Vue.component() expects.

  1. Added Vue.config.productionTip = false to jest setup

这只是禁用了关于在生产中使用开发构建的浏览器控制台警告,与自定义元素或组件注册无关。也许你打算使用 Vue.config.ignoredElements = ['rux-toggle'],这会消除关于未知自定义元素的警告(这在单元测试中实际上是不必要的),但它不会注册自定义元素。

解决方案

要在测试中正确使用 rux-toggle

  1. 创建一个注册 rux-toggle 的 Jest 安装文件。导入它就足够了,因为自定义元素注册是作为副作用发生的。

    // tests/jest.setup.js
    import '@astrouxds/rux-toggle'
    
  2. 配置 Jest 以使用安装文件:

    // jest.config.js
    module.exports = {
      setupFiles: ['<rootDir>/tests/jest.setup.js'],
    }
    
  3. 配置 Jest 转译 @astrouxds/rux-toggle:

    // jest.config.js
    module.exports = {
      transformIgnorePatterns: ['/node_modules//(?!@astrouxds/rux-toggle)'],
    }
    
  4. 您的项目使用jest24.9.0,依赖jsdom15,不支持自定义元素。要在此版本的 Jest 中启用自定义元素,请安装 jest-environment-jsdom-sixteen:

    npm install -D jest-environment-jsdom-sixteen
    
  5. 配置 Jest 以使用该测试环境:

    // jest.config.js
    module.exports = {
      testEnvironment: 'jest-environment-jsdom-sixteen',
    }
    
  6. 更新您的测试以使用 attributes('checked') 读取 checked 属性,并验证值为 "true"(属性为字符串值):

    it("test toggle default", () => {
      const result = wrapper.find('#app-toggle').attributes('checked');
      expect(result).toEqual('true');
    })
    

GitHub PR