DEV Community

Robert Wagner
Robert Wagner

Posted on • Originally published at shipshape.io

Unit Testing Private, Non-exported Functions with Rewire

Originally published at shipshape.io

When a JavaScript function is exported, it is straightforward to unit test.
We can import it directly into our test and test the functionality. For example,
we could use something like Jest to setup a simple import and unit test.

// foo.js

export function foo() {
  return 'bar';
}
Enter fullscreen mode Exit fullscreen mode
// foo.spec.js

import { foo } from './foo.js'

describe('Foo', () => {
  describe('foo', () => {
    expect(foo()).toBe('bar');
  });
});
Enter fullscreen mode Exit fullscreen mode

How would we test functions that we do not expose via export though?

There is a great tool, rewire, that allows getting references
to functions that are not explicitly exported. Assuming you are using Babel, we can use
babel-plugin-rewire to make the setup more simple.

  npm install babel-plugin-rewire --save-dev
Enter fullscreen mode Exit fullscreen mode

Then we need to add it to our plugins for testing, in our babel.config.js.

...
plugins: [
  'babel-plugin-rewire',
  ...
]
...
Enter fullscreen mode Exit fullscreen mode

We can then import the whole file, and get references to the non-exported functions, using
__get__.

// bar.js

function _bar() {
  return 'baz';
}
Enter fullscreen mode Exit fullscreen mode
// bar.spec.js

import Bar from './bar.js'

describe('Bar', () => {
  describe('_bar', () => {
    const _bar = Bar.__get__('_bar');
    expect(_bar()).toBe('baz');
  });
});
Enter fullscreen mode Exit fullscreen mode

Rewire makes this setup downright magical, and saves us from needing to needlessly export things
or use other hacks, just to get a reference to the function for testing. We can now ensure functions
remain private, without all the headaches at testing time!

Top comments (3)

Collapse
 
xiwcx profile image
i. welch canavan

🙏 genuinely been mulling this over lately. thanks for saving me from actually having to do the work 😆

Collapse
 
rwwagner90 profile image
Robert Wagner

Glad I could help!

Collapse
 
jesii profile image
Jon Seidel

Hmm... set this up as you described and I get:
TypeError: _EditFaxDetails.default.__get__ is not a function