使用Jest模拟在vue组件中导入的模块

j2cgzkjk  于 2023-09-28  发布在  Jest
关注(0)|答案(5)|浏览(138)

我在处理Jest的文档时遇到了一些问题,因为我希望这段代码能够工作:

import Vue from 'vue';
import Router from '@/router/index';
import OrdersService from '@/services/orders.service';

jest.mock('@/services/orders.service');

describe('OrdersItem.vue', () => {
  beforeEach(() => {
    // mockClear does not exist
    OrdersService.mockClear();
  });

  it('should render expected list contents', () => {
    // Orders.mock is undefined 
    OrdersService.getAll.mockResolvedValue([ ... ]);
    // ...

但事实并非如此。它失败了,好像OrdersService从来没有被嘲笑过。我也试过这样的东西:

jest.mock('@/services/orders.service', () => jest.fn());
jest.mock('@/services/orders.service', () => { getAll: jest.fn() });

第一个是用mock函数替换整个服务(我想实现文档中提到的自动mocking功能,其中原始的所有方法都自动替换为mock fn)。第二个失败的方式与只使用模块路径的.mock调用相同。
我做错了什么为什么?
orders.service backbone :

import axios from 'axios';
import config from '../config/config.json';
import Order from '../models/order';

class OrdersService {
  constructor(httpClient) {
    this.httpClient = httpClient;
  }

  getAll() {
      // ...
  }
}
export default new OrdersService(axios);
sq1bmfud

sq1bmfud1#

看起来jest.mock#4262)中有一个关于moduleNameMapper的模块解析器、别名、路径的问题,无论你想用@/something调用什么。

// you cannot use a module resolver (i.e. '@')
jest.mock('@/services/orders.service');

// you must use the full path to the file for the import and mock
import OrdersService from '../../src/services/orders.service';
jest.mock('../../src/services/orders.service');

请继续关注这个问题的更新,看起来最后一次更新是在9/28。
其次,如果您解决了上面的问题,您将导出一个类示例,而不是类本身,就像Jest示例中所做的那样。因此,您将无法访问OrdersService上的clearMock方法,而是可以在类示例上的每个模拟方法上调用clearMock

// mockClear will be undefined
OrdersService.mockClear();

// mockClear is defined
OrdersService.getAll.mockClear();

如果您想按原样导出示例,您可以使用beforeEach中的jest.clearAllMocks清除所有模拟,或者循环所有方法并在每个方法上调用mockClear。否则,导出类本身将给予您可以访问OrdersService.mockClear,这将...
清除所有示例和对构造函数的调用以及所有方法(ref)
这在模拟的类在您试图测试的另一个类中使用/示例化的情况下似乎很有用,就像在jest示例中一样。

  • 所有这些都已经使用Jest v23.6和vue-cli v3.0.4进行了测试和确认。*
mu0hgdu0

mu0hgdu02#

由于OrdersService是该类的一个示例,因此它将返回一个对象,您需要手动模拟该对象公开的所有属性。
您可以尝试使用以下实现来模拟您的函数。参照文档

OrdersService.getAll = jest.fn(()=>{
// mock implementation here;
});

希望这对你有帮助:)

nmpmafwu

nmpmafwu3#

您可以尝试在beforeEach块中调用jest.resetModules(),这可能会导致使用模拟的服务

xxls0lw8

xxls0lw84#

尝试使用别名导入所有内容,并在别名上设置mock。

import * as OrdersModule from '@/services/orders.service';
OrdersModule.getAll = jest.fn()

我在圣经里找到的:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules

qcbq4gxm

qcbq4gxm5#

遇到这个问题,在尝试让“mount”工作而不必手动设置一堆东西时遇到了一些问题,最简单的方法是导入模块:

import TestThisModule from 'testThisModule';

然后通过访问模块的原型,直接为我观察到的方法编写spyon来编写测试:

const resetMethodSpy = jest.spyOn(TestThisModule.prototype, 'reset');
const { wrapper } = factory();
await (wrapper.vm as any).triggerMethod();
expect(resetMethodSpy).toHaveBeenCalled();

相关问题