Proxyquire, rewire, SandboxedModule, and Sinon: pros & cons
Asked Answered
K

1

74

When mocking Node dependencies, I've happened upon the following libraries:

They all seem to do more-or-less the same thing: allow you to mock require() calls (with the exception of Sinon which mocks pretty much everything). They all seem to require some pretty elaborate setup, noting the exact syntax of the string passed to require -- not great during refactoring.

What are the pros and cons of each library? When would I choose one over the other? What are example use-cases where each library excels? What are other products in this space that are better?

Kalina answered 12/6, 2014 at 17:2 Comment(0)
K
149

It totally feels like cheating, but since no one else is answering the question, here goes:

  • Proxyquire takes over require and lets you inject fakes anywhere in the dependency chain. For requires you don't take over and for methods you don't define for requires you do take over, it'll fall back to the original. This can be disabled with noCallThru. Thus it still loads the original, just replaces things with the things you define. Unlike Rewire and SandboxedModule, you can't define global variables for your require overloads.

  • Rewire takes over require and injects __get__ and __set__ properties into each module. If you know the private variable name, you can replace it. Think dependency injection.

  • SandboxedModule is nearly identical to Proxyquire except it runs the entire process in a new V8 vm. (There is a per-test performance cost to this approach.) It also has a nasty bug in v 1.0 that makes it fail when something you didn't replace references a native module it doesn't support. See https://github.com/robrich/sandboxed-module-graceful-fs.

  • Sinon doesn't take over require like the other 3. Rather, it's a more traditional mocking framework. Replace specified methods with fakes, or create a mock that tracks when it was called.

Kalina answered 15/6, 2014 at 0:46 Comment(5)
Do you have any idea offhand how significant the "per-test performance cost" is? Or has anyone done any perf-tests? We use SandboxedModule, and it seems very slow. I've used proxyquire before and like it. Wondering if it's worth the dev effort to switch.Seedman
I've not run perf tests between them, but I converted a codebase from Sandboxed to Proxyquire (to get around the v1.0 bug) and accidentally yielded very significant performance gains.Kalina
One more: sinonquire (sinon taking over require) github.com/rstuven/sinonquire#readmeMozza
Are these all mutually exclusive though or can you mix and match any? For example rewire allows access to private modules but proxyquire doesn't seem to, so can you combine them?Galyak
Here's the reason why you shouldn't mix and match proxyquire and rewire according to the author of proxyquire, thlorenz github.com/thlorenz/proxyquire/issues/90Galyak

© 2022 - 2024 — McMap. All rights reserved.