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


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

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

есть ли лучшая структура для модульного тестирования модулей ES6?

5 52

5 ответов:

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

Я не могу говорить за traceur, который был основой, используемой в вопросе, но я обнаружил, что это работает с моей настройкой Karma, Jasmine и Babel, и я публикую его здесь, поскольку это, кажется, самый популярный вопрос этот тип.

я использовал эту стратегию чаще всего, когда нужно было издеваться над действиями 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
});

Если вы используете 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()
  })
})

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

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

привет вы могли бы использовать 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);
    });
});

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 не будет работать. Как долго можно издеваться над ФС - нельзя глумиться редукторы. Вы должны указать real имя зависимости, после любого преобразования webpack или babel. Обычно-имя относительно местоположения module1. Могут быть.' ./../../общей/основных/редукторы'. А может и нет.

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

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