it-roy-ru.com

Пересмешивание модуля, импортированного в компонент vue, с помощью Jest

У меня есть некоторые проблемы при обработке документации 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() });

Первый из них заменяет весь сервис фиктивной функцией (я хотел бы добиться того, чтобы функциональность автоматического имитации упоминалась в документации, где все методы из оригинала автоматически заменяются на фиктивную 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);
4
guessimtoolate

Похоже, есть проблема с 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. Следовательно, у вас не будет доступа к методу clearMock в OrdersService, но вы можете вызывать clearMock для каждого макетируемого метода в экземпляре класса.

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

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

Если вы хотите экспортировать экземпляр как есть, вы можете просто очистить все макеты с помощью jest.clearAllMocks в beforeEach или пройтись по всем методам и вызвать mockClear для каждого. В противном случае экспорт самого класса даст вам доступ к OrdersService.mockClear, который ...

Очистить все экземпляры и вызовы конструктора и всех методов (ref)

Это кажется полезным в тех случаях, когда макетный класс используется/создается в другом классе, который вы пытаетесь протестировать, как в примере с jest.

Все это было протестировано и подтверждено с использованием Jest v23.6 и vue-cli v3.0.4.

1
Nickofthyme

Поскольку OrdersService является экземпляром класса, он вернет объект, и вам нужно будет смоделировать все свойства, предоставляемые этим объектом, вручную.

Вы можете попробовать следующую реализацию для проверки вашей функции. Справочные документы

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

Надеюсь это поможет :)

1
Royson

Вы можете попытаться вызвать jest.resetModules() в блоке beforeEach, что может привести к использованию поддельной службы

0
Heather Roberts