如何在异步方法中测试 Vue 组件方法调用

How to test Vue Component method call within an async method

我相信我正在努力正确地模拟我的方法。这是我的情况,我有一个包含两种方法的组件;

    name: 'MyComponent',
    methods: {
       async submitAction(input) {
           // does await things
           // then ...
           this.showToastMessage();
       },
       showToastMessage() {
           // does toast message things
       },
    }

我想编写一个测试来断言 showToastMessage() 在调用 submitAction(input) 时被调用。我的基本测试看起来像这样;

    test('the toast alert method is called', () => {
      let showToastMessage = jest.fn();
      const spy = jest.spyOn(MyComponent.methods, 'showToastMessage');
      const wrapper = shallowMount(MyComponent, { localVue });

      const input = // some input data
      wrapper.vm.submitAction(input); // <--- this calls showToastMessage
      expect(spy).toHaveBeenCalled();
    };

注意:localVue 在文件顶部如此声明const localVue = createLocalVue();

我确认在测试期间调用了 submitAction()showToastMessage() 方法,方法是偷偷使用几个 console.log() 并在测试输出中观察它,但是测试仍然失败;

    expect(jest.fn()).toHaveBeenCalledWith(...expected)

    Expected: called with 0 arguments

    Number of calls: 0

      566 |           const wrapper = shallowMount(MyComponent, { localVue } );
      567 |           wrapper.vm.submitAction(input);
    > 568 |           expect(spy).toHaveBeenCalledWith();

我也试过监视这两种方法

    const parentSpy = jest.spyOn(MyComponent.methods, 'submitAction');
    const spy = jest.spyOn(MyComponent.methods, 'showToastMessage');
    // ...
    expect(spy).toHaveBeenCalled()

同样的结果,测试失败。

我错过了什么?

技术堆栈:vue 3、jest、节点 14

@TekkSparrow 您可以将一堆东西传递给 shallowMount 函数。它接受一个对象作为第二个参数,它看起来像

import { shallowMount, createLocalVue } from '@vue/test-utils'
import Vuex from 'vuex'

const localVue = createLocalVue()
localVue.use(Vuex)

let mocks = {
  // this could be something like the below examples
  // I had in a previous project
  $route: {
    query: '',
    path: '/some-path'
  },
  $router: [],
  $validator: {
    validateAll: jest.fn()
  },
  $toast: {
    show: jest.fn(),
    error: jest.fn()
  },
}
let propsData = {
  // some props you want to overwrite or test.
  // needs to be called propsData
}
let methods = {
  showToastMessage: jest.fn()
}
let store = new Vuex.Store({
  actions: {
    UPLOAD_ASSET: jest.fn(),
  },
})

const wrapper = shallowMount(MyComponent, { mocks, propsData, methods, store, localVue })

我相信通过执行与上述类似的操作,您的模拟函数将 运行 并被 Jest 间谍记录。

我花了一分钟 realize/try 这个,但看起来因为我的调用函数是异步的,所以我应该让我的测试异步,并等待主方法调用。这似乎已经成功了。这是我最终的解决方案:

    test('the toast alert method is called', async () => {
      let showToastMessage = jest.fn();
      const spy = jest.spyOn(MyComponent.methods, 'showToastMessage');
      const wrapper = shallowMount(MyComponent, { localVue });

      const input = // some input data
      await wrapper.vm.submitAction(input);
      expect(spy).toHaveBeenCalled();
    };