Подтвердить что ты не робот

Как заглушить экспортированную функцию в ES6?

У меня есть файл foo.js:

export function bar (m) {
  console.log(m);
}

И еще один файл, который использует foo.js, cap.js:

import { bar } from 'foo';

export default m => {
  // Some logic that I need to test
  bar(m);
}

У меня есть test.js:

import cap from 'cap'

describe('cap', () => {
  it('should bar', () => {
      cap('some');
  });
});

Как-то мне нужно переопределить реализацию bar(m) в тесте. Есть ли способ сделать это?

P.S. Я использую babel, webpack и mocha.

4b9b3361

Ответ 1

Ouch.. Я нашел решение, поэтому я использую sinon для заглушки и import * as foo from 'foo', чтобы получить объект со всеми экспортируемыми функциями, чтобы я мог их заглушить.

import sinon from 'sinon';
import cap from 'cap';
import * as foo from 'foo';

sinon.stub(foo, 'bar', m => {
    console.log('confirm', m);
});

describe('cap', () => {
  it('should bar', () => {
    cap('some');
  });
});

Ответ 2

Вы можете экспортировать/переписывать/заглушать только из самого модуля. (Здесь объяснение)

Если вы переписываете 'foo.js' следующим образом:

var bar = function bar (m) {
  console.log(m);
};

export {bar}

export function stub($stub) {
  bar = $stub;
}

Затем вы можете переопределить его в своем тесте следующим образом:

import cap from 'cap'
import {stub} from 'foo'

describe('cap', () => {
  it('should bar', () => {
      stub(() => console.log('stubbed'));
      cap('some'); // will output 'stubbed' in the console instead of 'some'
  });
});

Я создал плагин Babel, который автоматически преобразует все экспортные файлы, чтобы их можно было заколоть: https://github.com/asapach/babel-plugin-rewire-exports

Ответ 3

Вы можете использовать babel-plugin-rewire (npm install --save-dev babel-plugin-rewire)

И затем в test.js используйте функцию __Rewire__ на импортированном модуле, чтобы заменить функцию в этом модуле:

// test.js
import sinon from 'sinon'

import cap from 'cap'

describe('cap', () => {
  it('should bar', () => {
    const barStub = sinon.stub().returns(42);
    cap.__Rewire__('bar', barStub); // <-- Magic happens here
    cap('some');
    expect(barStub.calledOnce).to.be.true;
  });
});

Обязательно добавьте rewire к своим плагинам babel в .babelrc:

// .babelrc
{
  "presets": [
    "es2015"
  ],
  "plugins": [],
  "env": {
    "test": {
      "plugins": [
        "rewire"
      ]
    }
  }
}

Наконец, поскольку вы можете видеть, что плагин babel-plugin-rewire включен только в тестовой среде, поэтому вы должны называть вас тестировщиком с переменной окружения BABEL_ENV, установленной на test (которую вы, вероятно, уже делаете)

env BABEL_ENV=test mocha --compilers js:babel-core/register test-example.js

Примечание. Я не мог заставить babel-plugin-rewire-exports работать.