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

gue*_*ate 6 javascript unit-testing jasmine jestjs

我在处理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([ ... ]);
    // ...
Run Code Online (Sandbox Code Playgroud)

但是事实并非如此。如果OrdersService从未嘲笑过,它将失败。我也尝试过类似的东西:

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

第一个将整个服务替换为模拟功能(我想实现文档中提到的那种自动模拟功能,其中原始的所有方法都将被模拟fn自动替换)。第二个失败方式.mock与仅使用模块路径的调用相同。

我在这里做错什么,为什么?

orders.service 骨架:

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);
Run Code Online (Sandbox Code Playgroud)

Nic*_*yme 5

看起来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');
Run Code Online (Sandbox Code Playgroud)

请继续关注该问题的更新,看起来最后一次更新是在9/28

其次,如果您解决了上述问题,您将导出类实例而不是类本身,就像 Jest 示例中所做的那样。因此,您将无权访问clearMock上的方法OrdersService,但可以调用clearMock类实例上的每个模拟方法。

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

// mockClear is defined
OrdersService.getAll.mockClear();
Run Code Online (Sandbox Code Playgroud)

如果您想按原样导出实例,您可以清除所有jest.clearAllMocksbeforeEach或循环所有方法中使用的所有模拟并调用mockClear每个方法。否则导出类本身将使您OrdersService.mockClear能够访问...

清除所有实例以及对构造函数和所有方法的调用(参考)

在您尝试测试的另一个类中使用/实例化模拟类的情况下,这似乎很有用,如笑话示例中所示。

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


Hea*_*rts 0

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