thlorenz / proxyquireify

browserify >= v2 version of proxyquire. Mocks out browserify's require to allow stubbing out dependencies while testing.
MIT License
151 stars 24 forks source link

proxyquireify requires @noCallThru when stubbing ES6 modules? #58

Closed chrylis closed 8 years ago

chrylis commented 8 years ago

It's possible that I simply have things misconfigured, but the fact that I can get it working suggests a glitch in the plugin.

I'm writing my frontend JavaScript in ES6, run through babelify and then Browserify. I added proxyquireify to mock for testing, and I'm mocking ./multiplier/doubler:

export default function(x) { return 2 * x + 0; }

which is called from ./somemodule:

import foo from './multiplier/doubler';

export { foo as twice };

I wrote a Jasmine test case so:

const mocks = {
  './multiplier/doubler': (n) => 'something else',
};

const mocked = proxy('../src/js/somemodule', mocks).twice; // from 'test/spec.js'

describe('proxyquire', () => {
  it('loads', () => expect(proxy).toBeDefined());
  it('replaces the doubler', () => expect(mocked(3)).toEqual('something else'));
});

However, mocked(3) still returns the value 6 when I run this test. Adding @noCallThru to the mocks block makes the test behave as expected, which I interpret to mean that all of the module names (particularly the relative paths) are matching up correctly, but that proxyquireify is somehow skipping the mock definition in "normal" mode. Since this is the basic ES6-transform setup, it looks like a bug in the default behavior.

Edit: Changing the mock definition to { default: (n) => 'something else'; } makes it work without the @noCallThru. There's apparently a nonobvious relationship between callThru and the default module export that would be helpful to have documented.

bendrucker commented 8 years ago

Happy to add additional documentation if we add a test confirming expected behavior (in ES5). We don't officially support imports. We're happy to document gotchas with transpiling in the wiki if someone's willing to do the legwork to understand it.

chrylis commented 8 years ago

Ah, I had thought ES6 was supported--only parts, or is it just working because it's hitting babelify first?

bendrucker commented 8 years ago

Technically not at all. As you mention, it's only working because Babel is changing import to require. This is equally true of proxyquire (Node) and proxyquireify (browser). Some of this weird behavior must come down to how Babel is transpiling. That's why the wiki is the best place for info on this.