Как издеваться над зависимостями для модульных тестов с модулями ES6

Я пытаюсь возиться с модулями Ecmascript 6, используя webpack + traceur, чтобы перевести на ES5 CommonJS, но у меня проблемы с успешным тестированием модулей.

Я пробовал использовать препроцессор Jest + traceur, но имена automocking и dependency кажутся вялыми, и я не могу заставить sourceMaps работать с Jest и node -инспектором отладки.

Есть ли более эффективная структура для unit test модулей ES6?

Ответ 1

У меня на самом деле это получилось, если вы сбросили Jest и перешли с помощью Karma + Jasmine + Webpack и https://github.com/jhnns/rewire, чтобы издеваться над зависимостями

Ответ 2

Я начал использовать стиль import * as obj в моих тестах, который импортирует весь экспорт из модуля в качестве свойств объекта, который затем можно издеваться. Я считаю, что это намного чище, чем использование чего-то вроде rewire или proxyquire или любой другой подобной техники.

Я не могу говорить о трассировке, который был основой, используемой в вопросе, но я нашел, что это работает с моей настройкой Кармы, Жасмина и Вавилона, и я размещаю ее здесь, поскольку это, кажется, самый популярный вопрос этого типа.

Я использовал эту стратегию чаще всего, когда мне нужно было издеваться над действиями Redux. Вот краткий пример:

import * as exports from 'module-you-want-to-mock';
import SystemUnderTest from 'module-that-uses-above-module';

describe('your module', () => {
  beforeEach(() => {
    spyOn(exports, 'someNamedExport');  // mock a named export
    spyOn(exports, 'default');          // mock the default export
  });
  // ... now the above functions are mocked
});

Ответ 3

Если вы используете Webpack еще один вариант, который имеет немного большую гибкость, чем rewire, inject-loader.

Например, в тесте, который связан с Webpack:

describe('when an alert is dismissed', () => {

  // Override Alert as we need to mock dependencies for these tests
  let Alert, mockPubSub

  beforeEach(() => {
    mockPubSub = {}
    Alert =  require('inject!./alert')({
      'pubsub-js': mockPubSub
    }).Alert
  })

  it('should publish \'app.clearalerts\'', () => {
    mockPubSub.publish = jasmine.createSpy()
    [...]
    expect(mockPubSub.publish).toHaveBeenCalled()
  })
})

инжектор-загрузчик, аналогично тому, как proxyquire, по крайней мере, позволяет вводить зависимости перед импортом, тогда как в rewire вы должны сначала импортировать, а затем переделывать, что делает насмехающими некоторые компоненты (например, те, которые имеют некоторую инициализацию) невозможно.

Ответ 4

Привет, вы можете использовать proxyquire:

import assert from 'assert';
import sinon from 'sinon';
import Proxyquire from 'proxyquire';

let proxyquire = Proxyquire.noCallThru(),
    pathModelLoader = './model_loader';

describe('ModelLoader module.', () => {
    it('Should load all models.', () => {
        let fs, modelLoader, ModelLoader, spy, path;
        fs = {
            readdirSync(path) {
                return ['user.js'];
            }
        };
        path = {
            parse(data) {
                return {name: 'user'};
            }
        };
        ModelLoader = proxyquire(pathModelLoader, {'fs': fs, 'path': path});
        modelLoader = new ModelLoader.default();
        spy = sinon.spy(modelLoader, 'loadModels');
        modelLoader.loadModels();
        assert(spy.called);
    });
});

Ответ 5

Proxyquire поможет вам, но он не собирается работать с современными модулями webpack + ES6, то есть с "псевдонимами".

import fs from 'fs';
import reducers from 'core/reducers';
...
proxyquire('../module1', {
  'fs': mockFs,  // this gonna work
  'core/reducers': mockReducers // what about this?
});

that не будет работать. Пока вы можете издеваться над fs - вы не можете издеваться над редукторами. Вы должны указать real имя зависимости, после преобразования webpack или babel. Обычно - имя относительно местоположения модуля1. Может быть "../../../shared/core/reducers". Может и не быть.

Есть проблемы с решением - https://github.com/theKashey/proxyquire-webpack-alias (стабильный, основанный на fork proxyquire) или https://github.com/theKashey/resolveQuire (менее стабильный, может быть запущен на исходном прокси-сервере)

Оба они работают также и будут издеваться над любым модулем ES6 (они плохие) в прокси-ауте (это хороший способ)