Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mocking es6 modules in unit test

Suppose we have a file(source.js) to test:

// source.js
import x from './x';

export default () => x();

And the unit test code is very simple:

// test.js
import test from 'ava';
import source from './source'

test("OK", t => {
  source();
  t.pass();
});

But this is the tricky thing. The file "./x" does not exist in the test environment. Since it is a unit test, we do not need "./x". We can mock the function "x()" anyhow(using sinon or something else). But the unit test tool, ava, keeps showing "Error: Cannot find module './x'";

Is there any way to run the unit test without the file "./x"?

like image 763
Jim Jin Avatar asked Jan 18 '26 15:01

Jim Jin


2 Answers

To do this, you'd need to override the import process itself. There are libraries for doing something similar-- overriding the require function with proxyquire, for example-- but these force you to invoke their custom function to import the module under test. In other words, you'd need to abandon using ES6 module syntax to use them.

You should also note that ES modules are only supported experimentally (and relatively recently) in Node. If you're transpiling with Babel, you're not actually using ES modules. You're using the syntax, sure, but Babel transpiles them to CommonJS "equivalents", complete with require calls and module.exports assignments.

As such, if you're using Babel, you can probably proxyquire to import modules under test in your test files, even if you're using ES module syntax in those modules. This will break, though, if you ever switch away from Babel. :\

My personal recommendation would be to avoid directly exporting anything you might need to stub. So functions like x should be in a static module imported like import foo from './foo' and invoked like foo.x(). Then, you can easily stub it with sinon.stub(foo, 'x'). Of course, the './foo' file will have to exist for this still, but what it really comes down to is how hardcore you want to be about TDD practices versus how much complexity you're willing to introduce to your mocking/stubbing process. I prefer relaxing the former to avoid the latter, but in the end it's up to you.

like image 196
sripberger Avatar answered Jan 21 '26 05:01

sripberger


If you are using Jest, it can be achieved easily by mocking the import using the inbuilt mock method of jest. Please refer the link below to find more about ES6 import mocks

https://jestjs.io/docs/en/es6-class-mocks

like image 39
Sarath P S Avatar answered Jan 21 '26 06:01

Sarath P S



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!