无法使用 nuxt 和 jest 模拟服务

Unable to mock service with nuxt and jest

我有一个名为 External.vue 的组件,它包含一个带有道具的按钮,并且还有一个 Google 每次单击时都会触发的分析事件。

<template>
  <div>
    <button
      ref="ctaButtonExternalElement"
      type="submit"
      @click="fireEvent"
    >
      <a
        ref="ctaButtonExternalLinkElement"
        :class="ctaColour"
        class="block rounded-md border border-transparent px-4 py-3 font-medium shadow focus:outline-none focus:ring-2 focus:ring-offset-2 sm:px-6"
        :href="ctaLink"
      >
        {{ ctaTitle }}
      </a>
    </button>
  </div>
</template>


<script>
export default {
  props: {
    ctaTitle: {
      required: true,
      type: String,
    },
    ctaLink: {
      required: true,
      type: String,
    },
    ctaColour: {
      required: false,
      type: String,
      default: 'bg-blue-500 hover:bg-blue-700 focus:ring-blue-500',
    },
    event: {
      required: false,
      type: Object,
      default: function() {
        return {};
      },
    },
  },

  methods: {
    fireEvent() {
      if (this.event != null) {
        return this.$ga.event({
          eventCategory: this.event.event_category,
          eventAction: this.event.event_action,
          eventLabel: this.event.event_label,
          eventValue: this.event.event_value,
        });
      }
    },
  },
};
</script>

如您所见,this.$ga 由 nuxt 自动注入到此处,在我们的测试中,我们想要加载该组件,因此我们想要注入 $ga 或者更确切地说是它的模拟版本。

import {mount} from '@vue/test-utils';
import External from './External';
import ga from '@nuxtjs/google-analytics';
import {jest} from '@jest/globals';

describe('Test External Button', () => {
  test('should mock google analytics', async () => {
    const $ga = {ga: {
      event: jest.fn(),
    }};

    const wrapper = mount(External, {
      propsData: props,
      mocks: {
        $ga,
      },
    });

    const button = wrapper.getComponent({ref: 'ctaButtonExternalElement'});
    button.trigger('click');

    expect($ga).toHaveBeenCalled();
  });
});

当我 运行 这个测试时我得到这个错误:

 Test External Button › should mock google analytics

    expect(received).toHaveBeenCalled()

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

    Received has type:  object
    Received has value: {"ga": {"event": [Function mockConstructor]}}

Error in v-on handler: "TypeError: this.$ga.event is not a function"

有没有办法模拟$ga?

您的模拟看起来不正确。 $ga 没有 ga 属性,所以应该从 mock 中删除。

//const $ga = {ga: {
//  event: jest.fn(),
//}};

const $ga = {
  event: jest.fn(),
};

并且您将验证调用了 $ga.event,而不是 $ga。此外,还应等待 click-事件触发器,因为 click-处理程序直到下一个报价才会被调用:

//button.trigger('click');
//expect($ga).toHaveBeenCalled();

await button.trigger('click');
expect($ga.event).toHaveBeenCalled();