Coder Social home page Coder Social logo

lukemcgregor / node-require-subvert Goto Github PK

View Code? Open in Web Editor NEW

This project forked from rvagg/archived-node-require-subvert

0.0 1.0 0.0 9 KB

Yet another `require()` subversion library for mocking & stubbing

License: Other

JavaScript 100.00%

node-require-subvert's Introduction

Require Subvert Build Status

Yet another require() subversion library for mocking & stubbing.

Just show me the API!

Require Subvert is a very simple library with a very simple purpose: to subvert require() calls for modules that can't be easily mocked or stubbed. Specifically, modules whose export is simply a function.

For the case where a module exports an object that has child-functions, you don't need anything fancy for subverting require(). Consider the following code that uses Sinon for mocking:

var sinon = require('sinon')
  , foo = require('foo')
  , fooMock = sinon.mock(foo)

fooMock.expects('bar').once().withArgs(1, 2).returns(3)

assert(foo.bar() == 3)
fooMock.verify()

In this case, Sinon is simply replacing the exported API of 'foo' with a mock and because require() caches modules, the same module instance is shared across any other module requiring 'foo' in the same Node process (unless they are messing with the require cache). Nothing else needed!

But, if 'foo' was exported a function, e.g.:

module.exports = function (x, y) { ... }

then you'd be in a bit of trouble. Any other module that has already called require('foo') will have a reference to the original function and you can't take it back or overwrite it with a mock.

Enter Require Subvert. The solution is to replace the exports in the require cache and then reload any module that requires the module being mocked.

Assume that module 'foo' exports a function that we want to stub out and we want to test 'bar' which uses 'foo' foo internally:

// bar.js
var foo = require('foo')
module.exports.bang = function (x, y) {
  foo(x, y)
}

We can then stub 'foo' for our test of 'bar':

var sinon = require('sinon')
  , requireSubvert = require('require-subvert')(__dirname)
  , stub = sinon.stub()
  , bar

// subvert 'foo' with the stub
requireSubvert.subvert('foo', stub)
// (re)load 'bar', this fetches a fresh version of 'bar' after
// clearing it from the cache
bar = requireSubvert.require('bar')

// execute
bar.bang(1, 2)

// verify
assert(stub.callCount == 1)
assert(stub.getCall(0).args[0] == 1)
assert(stub.getCall(0).args[1] == 2)

// undo all our damage
requireSubvert.cleanUp()

API

RequireSubvert(__dirname)

You initialize Require Subvert by calling it with __dirname so it knows where the current module is located so any relative-path require() calls can be rewritten properly.

You can initialize Require Subvert in a few different ways, depending on your needs:

var requireSubvert = require('require-subvert')(__dirname)
// or
var RequireSubvert = require('require-subvert')
var instance = new RequireSubvert(__dirname)

Using the new operator may be helpful if you needed multiple instances for any reason, but remember that you're always operating on the same require cache no matter how many instances of Require Subvert you create!

subvert(name, replacement)

subvert() is how you provide a mock/stub to be used in place of module 'name'. The name can be whatever you would normally pass to require(), so it could be a global module, like 'fs', or something you have installed in node_modules). Or it could be a relative path (relative to the current module, even if you're testing a module in a different directory!), like '../lib/foo'.

require(name)

require() is what you should use in place of the global require() for any modules under test. It simply clears that module from the cache and reloads a fresh version that will use the stub/mock version(s) with its own require().

cleanUp()

cleanUp() should be called after you have finished with your subverted modules. It will restore the original versions in the require cache and also removed from the cache any modules you created with Require Subvert's own require() method.

Licence

Require Subvert is Copyright (c) 2012 Rod Vagg @rvagg and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.

node-require-subvert's People

Contributors

lukemcgregor avatar rvagg avatar timoxley avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.