javascript - 如何在 BootstrapVue 元素上使用 Vue Test Utils 触发事件?

标签 javascript vue.js dom bootstrap-vue vue-test-utils

这个问题让我很难受,我无法理解如何制作 Vue 测试工具 BootstrapVue 一起玩好。

一个最小的示例如下所示:

MyComponent.vue

<template>
  <div>
    <b-button variant="primary" @click="play">PLAY</b-button>
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
  methods: {
    play() {
      console.log("Let's play!");
    }
  }
}
</script>

main.js我们使用 BootstrapVue : Vue.use(BootstrapVue) .

这就是我尝试测试 click 的方式事件已被触发:
import { expect } from 'chai';
import sinon from 'sinon';
import Vue from 'vue';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import BootstrapVue, { BButton } from 'bootstrap-vue';
import MyComponent from '@/components/MyComponent.vue';

const localVue = createLocalVue();
localVue.use(BootstrapVue);

describe('MyComponent.vue', () => {
  it('should call the method play when button is clicked', () => {
    const playSpy = sinon.spy();
    const wrapper = shallowMount(MyComponent, {
      localVue,
      methods: {
        play: playSpy,
      },
    });
    wrapper.find(BButton).trigger('click');
    expect(playSpy.called).to.equal(true);
  });
});

这给了我:

  AssertionError: expected false to equal true
  + expected - actual

  -false
  +true


我查了How to test for the existance of a bootstrap vue component in unit tests with jest? ,但不适用于 BButton .

运行测试时,我在命令行上也看不到任何输出,我希望在此处执行此行:
console.log("Let's play!");

这里有什么问题?

最佳答案

事件原因click无法触发是怎么回事shallowMountmount 形成对比.

众所周知,Vue Test Utils 提供了两种挂载组件的方法,即渲染模板和生成 DOM 树:

  • 安装
  • 浅山

  • 第一种方法mount生成完整的 DOM 树并遍历所有子组件。大多数时候这不是必需的,所以方法 shallowMount是首选——它将子组件 stub 仅比父组件低一级。

    就我而言,这也是问题的根源。 BootstrapVue 提供组件,如 BButton ,可以在你自己的 Vue 模板中使用。这意味着在以下模板中:
    <template>
      <div>
        <b-button variant="primary" @click="play">PLAY</b-button>
      </div>
    </template>
    

    b 按钮 是一个子组件,在使用 shallowMount 时被 stub 在我们组件的单元测试中。这就是我们找不到元素按钮的原因:
    const wrapper = shallowMount(MyComponent);
    wrapper.find('button'); // won't work
    

    我们可以像这样找到子组件:
    wrapper.find(BButton); // BButton has to be imported from bootstrap-vue
    

    但是如果我们尝试输出渲染的元素:
    console.log(wrapper.find(BButton).element);
    

    我们会得到:
    HTMLUnknownElement {}
    
    BButton由于子组件尚未完全呈现,因此没有 button DOM 树中的元素。但是当我们使用 mount我们有这种行为:
    const wrapper = mount(MyComponent);
    console.log(wrapper.find(BButton).element);
    

    我们会得到:
    HTMLButtonElement { _prevClass: 'btn btn-primary' }
    

    我们看到 mount已经渲染了子组件。当我们使用 mount我们可以直接访问button元素:
    wrapper.find('button');
    

    现在我们有了 button我们可以触发像 click 这样的事件在上面。

    我希望这对其他初学者也有帮助。示例非常简化,不要忘记创建 localVue使用 createLocalVue并将其传递给 mount方法如问题所示。

    使用 时BootstrapVue 仔细考虑您需要哪种安装方法。

    关于javascript - 如何在 BootstrapVue 元素上使用 Vue Test Utils 触发事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60541806/

    相关文章:

    javascript - 元素偏移(包括滚动)

    javascript - Oracle Apex 19.1 - 单击按钮时的动态操作设置屏幕上的值将 Null 写入数据库

    javascript - "location.reload()"丢失 POST/SESSION 数据? (F5/Ctrl+R 保留数据?)

    vue.js - 如何发送 v-file-input 的内容?

    vue.js - 点击工具提示内容 vuetify

    javascript - 如何为同一元素上的同一事件调用/处理不同的事件处理程序? JavaScript

    javascript - vue 最奇怪的行为 - 注释代码正在运行

    javascript - 比较 innerHTML 和 jQuery

    javascript - 如何在 Vue 中动态创建的组件上获取更新的 $refs?

    JavaScript: "Dangling"引用 DOM 元素?