title: Jasmine mockability of imported vs required named exports
body: <p>I'll start with the setup, before I get into the problem. Let's start with the base file whose named exports we'll want to spy on:</p>
  
  <pre><code>// fileA.js
  export function bar() {}
  export function foo() {}
  </code></pre>
  
  <p>And then have two variations of classes that import these, one in CommonJS style, and one in ES6 style:</p>
  
  <pre><code>// es6Baz.js
  import * as A from 'fileA'
  
  export default class Baz {
    callFoo() { A.foo(); }
  }
  
  // commonBaz.js
  const A = require('fileA');
  
  export default class Baz {
    callFoo() { A.foo(); }
  }
  </code></pre>
  
  <p>Then likewise, test files for these two same variants:</p>
  
  <pre><code>// testEs6A.js
  import Baz from 'es6Baz';
  import * as A from 'fileA';    
  
  it('test', () =&gt; {
    spyOn(A, 'foo');
    const b = new Baz();
    b.callFoo();
    expect(A.foo).toHaveBeenCalled();  // this will fail
  });
  
  // testCommonA.js
  import Baz from 'es6Baz';
  const A = require('fileA');   
  
  it('test', () =&gt; {
    spyOn(A, 'foo');
    const b = new Baz();
    b.callFoo();
    expect(A.foo).toHaveBeenCalled(); // this will pass
  });
  </code></pre>
  
  <p><strong>The main question here is</strong>: why does mocking work with the CommonJS approach, but not the ES6 one, assuming we're using Babel to compile?</p>
  
  <p>My understanding was that ES6 live binds, while CommonJS copies, so I was surprised the former failed, and even more surprised the latter succeeded. My best guess is that a * import results in a locally namespaced object that's different in the files this is done in (i.e. <code>A</code> in <code>es6Baz.js</code> is not the same as <code>A</code> in <code>testEst6A.js</code>), but is that actually the case? And why would the <code>require</code> work, when this doesn't?</p>