i-like-robots / rewireify

Rewireify is a port of Rewire for Browserify that adds setter and getter methods to each module so that their behaviour can be modified for better unit testing.
https://www.npmjs.com/package/rewireify
Other
59 stars 10 forks source link

the "right" way of testing nested modules #7

Closed OscarGodson closed 9 years ago

OscarGodson commented 9 years ago

So, I'm using React and React Router. React Router makes it very hard to test because you need a full router initialized and working to use any part of it so I thought rewireify would be perfect. I'm including it in my build like:

function startWatchify () {
  var bundle = new browserify(manifestFilePath, { ... });

  bundle.transform("rewireify");

  watchedBundle = watchify(bundle);

  watchedBundle.on('update', function() {
    bundleAndSave(watchedBundle);
  });

  bundleAndSave(watchedBundle);
};

I then have a Sidebar component which requires a NavItem. NavItem requires var Link = require('react-router').Link;

As it stands, doing this pretty much makes things implode for the reasons I said above. This is documented on their side and they are working on it I guess.

I figured since I don't need to unit test that Link works I can simply stub it out and make require('react-router') just return a stubbed class like

{
  Link: function () {
    // This really doesn't do anything
    return new StubbedOutReactComponent();
  }
}

From the Sidebar tests which requires Sidebar that requires NavItem which requires require('react-router').Link, how do I stub out that require('react-router').Link from the Sidebar tests? or, is that even possible? How would you suggest going about stubbing that out?

i-like-robots commented 9 years ago

With Rewireify this is not possible because it does not override the default require behaviour. There are other tools available that do and therefore enable you to re-map dependencies.

If you really want to use Rewireify it's probably best to consider: Is unit testing really suitable for these tests, would integration testing be better? Can the dependency graph be simplified or can the React Router dependency be passed through in a sane way?

OscarGodson commented 9 years ago

The only way I've found to get react router to semi-work is by wrapping every module in my tests with a stub function that mixes in stubbed versions of every method in react router. Its super clunky and causes other weird issues. The dep graph in this case is pretty simple unfortunately. Its just 2 deep when it fails: Sidebar > NavItem.

You mentioned remapping deps with stubbed out ones. Do you mean like https://github.com/thlorenz/proxyquireify ? or do you have other suggestions?

i-like-robots commented 9 years ago

That sort of thing yeah, I can't recommend anything though as I haven't actually used such a solution in anger. Did you look at Jest already?