【问题标题】:Testing vue with a web component使用 web 组件测试 vue
【发布时间】:2021-10-02 13:00:07
【问题描述】:

我的应用程序正在使用 astrouxds Web 组件,我在我的测试中收到一条警告,我想修复它。我也不确定如何断言 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. 已将 Vue.config.productionTip = false 添加到笑话设置中

【问题讨论】:

  • 为什么你在 main.js 文件中而不是在 App.vue 文件中导入 RuxToggle 组件并将其正确添加到你的 App.vue 组件的 components 属性中?
  • 如果你想全局注册它,你应该在 main.js 文件中添加Vue.component('rux-toggle', RuxToggle)。否则,像这样导入组件并忽略 eslint 告诉您您正在做一些可疑的事情是没有意义的:D
  • 我不能 100% 确定导入的文件底部有 customElements.define('rux-toggle', RuxToggle);。我想也许这应该是全局的,而不是在使用它的每个组件中。
  • 是的,不,我只是愚蠢,我实际上认为 rux 是一个“正常”组件,但在考虑了你的问题之后,它显然是一个你想要使用的 Web 组件:D 抱歉。我相信这个问题还有另一个答案可以解决您的问题。没错here
  • 您可以通过为 jest 添加一个设置文件来避免这些问题(我假设您正在使用 jest?)因此将 index.jsindex.ts 文件添加到您的测试目录或其他位置。您将在其中输入Vue.config.productionTip = false;。然后将setupFiles: ["&lt;rootDir&gt;/tests/index.ts"] 添加到您的 jest.config.js 文件中。

标签: vue.js vuejs2 jestjs web-component vue-test-utils


【解决方案1】:

rux-toggle 组件仅在main.js 中注册,导致您观察到的警告/错误。

关于你的尝试:

  1. 从 shallowMount 切换到 mount

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

  1. 使用 Vue.component(rux-toggle, RuxToggle) 全局注册

@astrouxds/rux-toggle 中的RuxToggle 是一个LitElement,不满足Vue.component() expectsVue 组件定义的要求。

  1. Vue.config.productionTip = false 添加到笑话设置中

这只是禁用了有关在生产中使用开发人员构建的浏览器控制台警告,与自定义元素或组件注册无关。也许您打算使用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. 您的项目使用jest 24.9.0,它依赖于不支持自定义元素的jsdom 15。要在此版本的 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

【讨论】:

  • 谢谢!这一切都奏效了。我的团队现在可以编写测试了!
猜你喜欢
  • 2019-04-19
  • 2018-07-25
  • 2019-07-16
  • 2023-01-03
  • 1970-01-01
  • 2019-03-20
  • 2020-12-01
  • 1970-01-01
  • 2019-03-11
相关资源
最近更新 更多