How to stub exported function in ES6?

I have file foo.js:

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

And another file that uses foo.js, cap.js:

import { bar } from 'foo';

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

I have test.js:

import cap from 'cap'

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

Somehow I need override implementation of bar(m) in test. Is there any way to do this?

P.S. I use babel, webpack and mocha.


Solution 1:

Ouch.. I found solution, so I use sinon to stub and import * as foo from 'foo' to get object with all exported functions so I can stub them.

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');
  });
});

Solution 2:

You can replace/rewrite/stub exports only from within the module itself. (Here's an explanation)

If you rewrite 'foo.js' like this:

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

export {bar}

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

You can then override it in your test like this:

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'
  });
});

I've created a Babel plugin that transforms all the exports automatically so that they can be stubbed: https://github.com/asapach/babel-plugin-rewire-exports