【问题标题】:Cannot access emit property while testing click event on Vue 3在 Vue 3 上测试点击事件时无法访问发出属性
【发布时间】:2022-02-12 01:50:38
【问题描述】:

我是测试新手,我正在尝试使用 Vue test-utils 测试一个组件,但是当我尝试测试对导入组件的点击时遇到了问题。

这是我的测试文件:

  import { Table, Input } from 'ant-design-vue';
  import { CheckOutlined, EditOutlined } from '@ant-design/icons-vue';
  
  import { shallowMount } from '@vue/test-utils';
  let wrapper;
  beforeEach(() => {
    wrapper = shallowMount(TableEditable, {
      global: {
        components: {
          'a-table': Table,
          'a-input': Input,
          'check-outlined': CheckOutlined,
          'edit-outlined': EditOutlined,
        }
      },
      emits: ['edit', 'save'],
      props: {
        tableData: {
          "data":[
            {"id":"0","monday":"0"}],
          "columns":[
            {"title":"Mon","dataIndex":"monday","slots":{"customRender":"monday"}}]
        },
        dataSrc: [{"id":"0","monday":"0","tuesday":"0","wednesday":"0","thursday":"0","friday":"0","saturday":"9","sunday":"10","key":"0"}]
      }
    })
  })
  
  describe('first test', () => {
    it('first test: check if theres a class name', () => {
      expect(wrapper.classes()).toContain('tableEditable')
    })
    it('click and emit buttons', async () => {
        await wrapper.findComponent({ref: 'edit-outlined'})
        await wrapper.trigger('click')
        expect(wrapper.emitted()).toHaveProperty('edit')
  
      })
  })

这是我的组件:

  <template>
     <a-table bordered :data-source="dataSrc" :columns="tableData.columns" :pagination="false" class="tableEditable">
      <template #title>
        <div class="formLayoutCrud">
          <p>{{this.title}}</p>
          <input-multiple-button :name="'buttonOptions'" :value="'percentage'" :options="this.buttonOptions"> </input-multiple-button>
        </div>
      </template>
      <template v-for="col in this.editableCells" #[col]="{ column, text, record }" :key="col">
        <div class="editable-cell">
          <div v-if="editableTableData[record.key + '|' + column.key] !== undefined" class="editable-cell-input-wrapper">
            <a-input v-model:value="editableTableData[record.key + '|' + column.key]" @pressEnter="save(record.key, column.key)" type="number" />
            <check-outlined class="editable-cell-icon-check" @click="save(record.key, column.key)" />
          </div>
          <div v-else class="editable-cell-text-wrapper">
            {{ text || ' ' }}
            <edit-outlined class="editable-cell-icon" @click="edit(record.key, column.key)" />
          </div>
        </div>
      </template>
    </a-table>
  </template>
  <script>
  
  import { CheckOutlined, EditOutlined } from '@ant-design/icons-vue';
  
  import InputMultipleButton from '@/components/crudForm/InputMultipleButton.vue';
  
  export default {
    name: 'TableEditable',
    props: {
      title: String,
      buttonOptions: Array,
      editableCells: Array,
      tableData: Object,
      dataSrc: Array,
      editableDataProp: Object
    },
    emits: ['edit', 'save'],
    components: {
      CheckOutlined,
      EditOutlined,
      InputMultipleButton
    },
    data(){
      return {
        editableTableData: this.editableDataProp
      }
    },
    methods: {
      edit(row, column) {
        this.$emit('edit', row, column)
      },
      save(row, column) {
        this.$emit('save', row, column)
      }
    }
  }
  </script>
  <style>

这是我运行 npm test 时遇到的错误

  > vue-cli-service test:unit "TableEditable.spec.js"
  
   FAIL  tests/unit/components/crudForm/TableEditable.spec.js
    checkbox first tests
    ✓ first test: check if theres a class name (18ms)
    ✕ click and emit buttons (7ms)
  
    ● checkbox first tests › click and emit buttons
  
    expect(received).toHaveProperty(path)
  
    Expected path: "edit"
    Received path: []
  
    Received value: {"click": [[{"isTrusted": false}]]}
  
      38 |       // await wrapper.vm.$nextTick()
      39 |       await wrapper.trigger('click')
    > 40 |       expect(wrapper.emitted()).toHaveProperty('edit')
       |                     ^
      41 |
      42 |     })
      43 | })
  
      at Object.<anonymous> (tests/unit/components/crudForm/TableEditable.spec.js:40:39)
  
  Test Suites: 1 failed, 1 total
  Tests:     1 failed, 1 passed, 2 total
  Snapshots: 0 total
  Time:      4.653s
  Ran all test suites matching /TableEditable.spec.js/i.

正如我所说,很抱歉,如果这是一个简单的错误,但我开始学习测试,所以我没有很多经验。如果有人需要更多信息,请告诉我。提前致谢!

【问题讨论】:

    标签: jestjs vuejs3 vue-test-utils


    【解决方案1】:

    据我所知,expect(wrapper.emitted()).toHaveProperty('edit') 应该可以工作。

    所以我认为问题在于点击没有按预期工作

    你有

    await wrapper.findComponent({ref: 'edit-outlined'})
    await wrapper.trigger('click')
    

    • 在包装器中找到edit-outlined 按钮
    • 点击组件/包装器(不是按钮)

    要解决这个问题,您可以尝试像这样链接它:

    await wrapper
      .findComponent({ref: 'edit-outlined'})
      .trigger('click');
    

    这里的触发器赋值给findComponent的结果

    更新

    我相信wrapper.findComponent({ref: 'edit-outlined'}) 没有找到该组件。当使用ref 时,它将在 ref 属性中查找具有该值的组件。

    你有

    <div v-else class="editable-cell-text-wrapper">
      {{ text || ' ' }}
      <edit-outlined class="editable-cell-icon" @click="edit(record.key, column.key)" />
    </div>
    

    edit-outlined 是组件的名称/类型,而不是引用。

    你可以改成

    <div v-else class="editable-cell-text-wrapper">
      {{ text || ' ' }}
      <edit-outlined ref="edit-outlined" class="editable-cell-icon" @click="edit(record.key, column.key)" />
    </div>
    

    这会将其放入this.$refs 内部对象(特别是this.$refs['edit-outlined'])中,这样就可以使用wrapper.findComponent({ref: 'edit-outlined'}) 访问它。

    您还应该能够更改定位该元素的方式,这应该使其在不更改您正在测试的代码的情况下工作。

    findcomponent 有三种类型可以作为选择器参数传递。

    {Component|ref|string} selector

    如果您只有一个实例或EditOutlined,您可以使用Component 类型来定位它,如下所示:

    const btn = wrapper.findComponent(EditOutlined);
    expect(btn.exists()).toBe(true);
    await btn.trigger('click');
    

    另外,添加这些是个好主意:expect(btn.exists()).toBe(true);它们充当“健全性测试”,并确保当您遇到错误时,您正在寻找正确的位置。

    【讨论】:

    • 仍然无法正常工作并给我同样的错误。 :/ 不知道我错过了什么。
    • 我想我明白发生了什么。我相信{ref: 'edit-outlined'} 不会像您认为的那样做。我会更新答案。
    • 我尝试了两种可能的解决方案,但都没有成功,也尝试了#id,但也没有成功。我不知道该怎么做,但感谢您的回答。
    • 您可以尝试 console.logging 包装器的 .html() 响应。这可能有助于调试。
    猜你喜欢
    • 2021-03-02
    • 2020-10-10
    • 2018-02-09
    • 2021-02-04
    • 2021-03-12
    • 1970-01-01
    • 2022-01-09
    • 2021-07-06
    相关资源
    最近更新 更多