How to run Jest tests with Rewire plugin
Another Jest connected post. How to test internal module functions that are not exported?
Problem
I want to test internal function defined inside ./index.js file without exporting it with module.exports
. Let say that ./index.js looks similar to this (implementation details are irrelevant):
function someFunction(something) {
return 'anything';
}
This function is not a part of public interface so exporting it just for testing with Jest seems like a bad idea/solution. Of course the following test won't work:
const someFunction = require('./index').__get__('someFunction');
describe('someFunction', () => {
it('should work', () => {
expect(someFunction()).toEqual('anything');
});
});
The error message may looks as follows:
TypeError: require(...).__get__ is not a function
This is caused by lack of rewire package (as you may expect).
Solution
Use babel-plugin-rewire it's extremly easy to do. Just:
- Install it with
yarn add --dev babel-plugin-rewire
- If you don't have
babel-jest
installed execute alsoyarn add --dev babel-jest
- Add plugin to the .babelrc config file:
{
"plugins": ["babel-plugin-rewire"]
}
Now just run your tests as usual yarn jest
. Everything should work smoothly.
You don't have to install rewire
itself.
If you are trying/willing to run Jest tests with Flow typed Javascript files check my other article Running Jest tests with Flow typed Javascript files.
Issues
The one which cost me a lot of time to figure it out.
TypeError: _get__(...) is not a function
According to the @joshnuss Github answer with babel-plugin-rewire you can't actually use __get__
method (or any other e.g. __Rewire__
) for function/constant which is not referenced anywhere in your module file.
Example of a "buggy" module code which you won't be able to rewire and use __get__
method.
const test123 = () => {
return true;
}
A "fixed" version (just reference test123
anywhere it doesn't have to be even executed):
const test123 = () => {
return true;
}
test123;
And here is a test case which will fail if we use "buggy" implementation of the module.
const test123 = require('./index').__get__('test123');
test('test123', () => {
expect(test123()).toEqual(true);
});
When such case might happen? Well, for example if you try to test some currently unused function (e.g. just a new internal module function).
Sources
https://www.npmjs.com/package/babel-plugin-rewire https://github.com/facebook/jest/issues/1003 https://www.npmjs.com/package/babel-plugin-rewire