Mocking Named Imports in Node.js
foo.js
bar.js
Bad way to test bar.js
The following works, but it is because of a babel transpilation implementation detail.
What should happen here is that bar has a pointer directly to sayFoo before our test setup executes. When our test setup executes, it changes pointer foo.sayFoo to point to a mock implementation, but that doesn’t affect bar’s pointer which still points to the real sayFoo.
So why does this work? If we go to http://babeljs.io/repl/ and paste the contents of bar.js
, we get the following:
Whaaaaat? Rather than destructuring the module and making a pointer sayFoo
that points directly to the function, it imports the entire module as an object and updates all your calls to sayFoo to be via that imported object.
Let’s change our implementation of bar.js as follows:
bar.js with destructuring
And now our test fails because it calls the real implementation of sayFoo, not the mocked one.
Why is this a problem? Because when we have a real implementation of javascript modules in the near future and you want to start using that, you may find that suddenly you have a ton of tests failing. :(
My suggestion, don’t rely on this bebel implementation detail. I suggest the following pattern for testing bar.js instead: