【问题标题】:Testing that a value is passed to a method that emits an event, Vue测试一个值是否传递给一个发出事件的方法,Vue
【发布时间】:2021-05-10 00:16:21
【问题描述】:

我有一个子组件,它根据作为道具传递的对象数组呈现按钮。这 传递给事件处理程序的值是一个如下所示的对象:{ boxes: 1, cookieQty: 4, id: 'chocChip-4', price: 12 }

<ul class="list-items">
      <li v-for="(item, index) in items" :key="item.id">
        <label :for="item.id" class="label-btn-cookie">{{ title }}</label>
        <button
          :id="item.cookieid"
          v-bind="$attrs"
          type="button"
          :value="item.cookieQty"
          class="cookie-buttons -shadow"
          @click="updateSelection(item)"
        >
          ...
          ...
        </button>

          methods: {
            updateSelection(value) {
              this.$emit("click", value);
             }
           }

在 Parent 组件中,Child 看起来像这样,'selectboxSize' 接受 $event 然后调度一个动作。

          <CookieSelect
            :items="chocChipBoxSizesArray"
            :title="chocChip"
            data-cookie="chocolateChip"
            @click="selectBoxSize($event)"
          />

          ....

         selectBoxSize({ cookieQty }) {
          // map the element to an object and use that key to update state
          console.log(event);
          let element = event.currentTarget.getAttribute("data-cookie");
          this.updateBoxSize({ element, cookieQty });

目前我有一个通过测试来验证按钮单击会发出一个事件。 我要做的是测试“updateSelection”实际上是用传递的值调用的。

   const mockData = {
     items: chocChipBoxSizesArray,
     title: "ChocolateChip"
   };

   describe("CookieSelect", () => {
     const wrapper = shallowMount(CookieSelect, {
      localVue,
      propsData: { ...mockData }
     });
      it("emits click when clicked", () => {
       const value = { boxes: 1, cookieQty: 4, id: "chocChip-4", price: 12 };
       wrapper.find("button").trigger("click");
       expect(wrapper.emitted("click")).toHaveLength(1); // passes
       expect(wrapper.emitted("click")).toHaveBeenCalledWith(value); // error
     });
...

这是我得到的错误:

expect(received).toHaveBeenCalledWith(...expected)

    Matcher error: received value must be a mock or spy function

    Received has type:  array
    Received has value: [[{"boxes": 1, "cookieQty": 4, "id": "chocChip-4", "price": 12}]]

我试过间谍和嘲笑一个新的MouseEvent() 无济于事。

【问题讨论】:

  • 为什么你想测试updateSelection被调用了吗?这是一个实现细节,听起来您已经在测试行为(发出正确的值)。当你开始监视你应该测试的东西时,你将自己与它的内部联系得太紧密了。

标签: javascript vue.js jestjs vue-test-utils


【解决方案1】:

您必须在 updateSelection 上设置一个间谍来验证它的调用,而 wrapper.emitted() 不会为您这样做。

在安装前使用jest.spyOn() 在导入的组件定义上创建一个间谍。还要确保等待click 触发器,以确保点击的任何副作用都已解决:

import CookieSelect from '@/components/CookieSelect.vue'

it('emits click when called', async () => {
  const updateSelection = jest.spyOn(CookieSelect.methods, 'updateSelection')
  const wrapper = shallowMount(CookieSelect)
  await wrapper.find('button').trigger('click')

  const value = /*...*/
  expect(updateSelection).toHaveBeenCalledWith(value)
})

【讨论】:

  • 好的,我异步和同步都试过了,都通过了。我猜想一些下游副作用可能来自调度操作然后提交突变。作为一般规则,应该在设置浅挂载包装器之前在文件顶部设置所有间谍,或者可能在 beforeEach()... 你的想法。
  • 我认为 spy/mock 设置的位置取决于要测试的具体实现和个人喜好。我个人创建的间谍/模拟尽可能接近相应的断言(并且在同一个测试中),这使得对预期结果的推理变得容易。如果需要,这也允许我在每个测试中以不同方式模拟某些调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-22
  • 1970-01-01
相关资源
最近更新 更多