programing

ES6 모듈을 사용하여 단위 테스트에 대한 종속성을 모의하는 방법

nasanasas 2020. 12. 31. 08:28
반응형

ES6 모듈을 사용하여 단위 테스트에 대한 종속성을 모의하는 방법


webpack + traceur를 사용하여 Ecmascript 6 모듈을 사용하여 ES5 CommonJS로 트랜스 파일하려고 시도하고 있지만 성공적으로 단위 테스트하는 데 문제가 있습니다.

Jest + traceur 전처리기를 사용해 보았지만 자동 모의 및 종속성 이름이 엉망인 것 같고 Jest 및 노드 검사기 디버깅과 함께 작동하도록 sourceMaps를 가져올 수없는 것 같습니다.

ES6 모듈 단위 테스트를위한 더 나은 프레임 워크가 있습니까?


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에서는 먼저 가져온 다음 다시 연결해야 일부 구성 요소 (예 : 일부 초기화가있는 구성 요소)를 조롱하는 것이 불가능합니다.


실제로 Jest를 삭제하고 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작동 안 할 것이다. fs를 모의 할 수있는 한-감속기를 모의 할 수 없습니다. real웹팩 또는 바벨 변환 후에 종속성 이름 을 지정해야합니다 . 일반적으로-module1 위치에 상대적인 이름입니다. '../../../shared/core/reducers'일 수 있습니다. 아마.

There is drop in solutions - https://github.com/theKashey/proxyquire-webpack-alias (stable, based on fork of proxyquire) or https://github.com/theKashey/resolveQuire (less stable, can be run upon original proxyquire)

Both of them works as well, and will mock any ES6 module(they are dam good) in a proxyquire way(it is a good way)

ReferenceURL : https://stackoverflow.com/questions/27323031/how-to-mock-dependencies-for-unit-tests-with-es6-modules

반응형