• Stars
    star
    2,741
  • Rank 16,210 (Top 0.4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 12 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🔮 Proxies nodejs require in order to allow overriding dependencies during testing.

proxyquire Build Status

Proxies nodejs's require in order to make overriding dependencies during testing easy while staying totally unobtrusive.

If you want to stub dependencies for your client side modules, try proxyquireify, a proxyquire for browserify v2 or proxyquire-universal to test in both Node and the browser.

Features

  • no changes to your code are necessary
  • non overridden methods of a module behave like the original
  • mocking framework agnostic, if it can stub a function then it works with proxyquire
  • "use strict" compliant

Example

foo.js:

var path = require('path');

module.exports.extnameAllCaps = function (file) {
  return path.extname(file).toUpperCase();
};

module.exports.basenameAllCaps = function (file) {
  return path.basename(file).toUpperCase();
};

foo.test.js:

var proxyquire =  require('proxyquire')
  , assert     =  require('assert')
  , pathStub   =  { };

// when no overrides are specified, path.extname behaves normally
var foo = proxyquire('./foo', { 'path': pathStub });
assert.strictEqual(foo.extnameAllCaps('file.txt'), '.TXT');

// override path.extname
pathStub.extname = function (file) { return 'Exterminate, exterminate the ' + file; };

// path.extname now behaves as we told it to
assert.strictEqual(foo.extnameAllCaps('file.txt'), 'EXTERMINATE, EXTERMINATE THE FILE.TXT');

// path.basename and all other path module methods still function as before
assert.strictEqual(foo.basenameAllCaps('/a/b/file.txt'), 'FILE.TXT');

You can also replace functions directly:

get.js:

var get    = require('simple-get');
var assert = require('assert');

module.exports = function fetch (callback) {
  get('https://api/users', callback);
};

get.test.js:

var proxyquire = require('proxyquire').noCallThru();
var assert = require('assert');

var fetch = proxyquire('./get', {
  'simple-get': function (url, callback) {
    process.nextTick(function () {
      callback(null, { statusCode: 200 })
    })
  }
});

fetch(function (err, res) {
  assert(res.statusCode, 200)
});

Table of Contents generated with DocToc

Usage

Two simple steps to override require in your tests:

  • add var proxyquire = require('proxyquire'); to top level of your test file
  • proxyquire(...) the module you want to test and pass along stubs for modules you want to override

API

proxyquire({string} request, {Object} stubs)

  • request: path to the module to be tested e.g., ../lib/foo
  • stubs: key/value pairs of the form { modulePath: stub, ... }
    • module paths are relative to the tested module not the test file
    • therefore specify it exactly as in the require statement inside the tested file
    • values themselves are key/value pairs of functions/properties and the appropriate override

Preventing call thru to original dependency

By default proxyquire calls the function defined on the original dependency whenever it is not found on the stub.

If you prefer a more strict behavior you can prevent callThru on a per module or contextual basis. If your stub is a class or class instance rather than a plain object, you should disable callThru to ensure that it is passed through with the correct prototype.

class MockClass {
  static '@noCallThru' = true;
}

var foo = proxyquire('./foo', {
  './my-class': MockClass
});
class MockClass {
  get '@noCallThru'() {
    return true;
  }
}

var foo = proxyquire('./foo', {
  './my-class-instance': new MockClass()
});

If callThru is disabled, you can stub out modules that don't even exist on the machine that your tests are running on. While I wouldn't recommend this in general, I have seen cases where it is legitimately useful (e.g., when requiring global environment configs in json format that may not be available on all machines).

Prevent call thru on path stub:

var foo = proxyquire('./foo', {
  path: {
      extname: function (file) { ... }
    , '@noCallThru': true
  }
});

Prevent call thru for all future stubs resolved by a proxyquire instance

// all stubs resolved by proxyquireStrict will not call through by default
var proxyquireStrict = require('proxyquire').noCallThru();

// all stubs resolved by proxyquireNonStrict will call through by default
var proxyquireNonStrict = require('proxyquire');

Re-enable call thru for all future stubs resolved by a proxyquire instance

proxyquire.callThru();

Call thru configurations per module override callThru():

Passing @noCallThru: false when configuring modules will override noCallThru():

var foo = proxyquire
    .noCallThru()
    .load('./foo', {

        // no calls to original './bar' methods will be made
        './bar' : { toAtm: function (val) { ... } }

        // for 'path' module they will be made
      , path: {
          extname: function (file) { ... }
        , '@noCallThru': false
        }
    });

All together, now

var proxyquire = require('proxyquire').noCallThru();

// all methods for foo's dependencies will have to be stubbed out since proxyquire will not call through
var foo = proxyquire('./foo', stubs);

proxyquire.callThru();

// only some methods for foo's dependencies will have to be stubbed out here since proxyquire will now call through
var foo2 = proxyquire('./foo', stubs);

Using proxyquire to simulate the absence of Modules

Some libraries may behave differently in the presence or absence of a package, for example:

var cluster;
try {
  cluster = require('cluster');
} catch(e) {
  // cluster module is not present.
  cluster = null
}
if (cluster) {
  // Then provide some functionality for a cluster-aware version of Node.js
} else {
  // and some alternative for a cluster-unaware version.
}

To exercise the second branch of the if statement, you can make proxyquire pretend the package isn't present by setting the stub for it to null. This works even if a cluster module is actually present.

var foo = proxyquire('./foo', { cluster: null });

Forcing proxyquire to reload modules

In most situations it is fine to have proxyquire behave exactly like nodejs require, i.e. modules that are loaded once get pulled from the cache the next time.

For some tests however you need to ensure that the module gets loaded fresh everytime, i.e. if that causes initializing some dependency or some module state.

For this purpose proxyquire exposes the noPreserveCache function.

// ensure we don't get any module from the cache, but to load it fresh every time
var proxyquire = require('proxyquire').noPreserveCache();

var foo1 = proxyquire('./foo', stubs);
var foo2 = proxyquire('./foo', stubs);
var foo3 = require('./foo');

// foo1, foo2 and foo3 are different instances of the same module
assert.notStrictEqual(foo1, foo2);
assert.notStrictEqual(foo1, foo3);

proxyquire.preserveCache allows you to restore the behavior to match nodejs's require again.

proxyquire.preserveCache();

var foo1 = proxyquire('./foo', stubs);
var foo2 = proxyquire('./foo', stubs);
var foo3 = require('./foo');

// foo1, foo2 and foo3 are the same instance
assert.strictEqual(foo1, foo2);
assert.strictEqual(foo1, foo3);

Globally override require

Use the @global property to override every require of a module, even transitively.

Caveat

You should think very hard about alternatives before using this feature. Why, because it's intrusive and as you'll see if you read on it changes the default behavior of module initialization which means that code runs differently during testing than it does normally.

Additionally it makes it harder to reason about how your tests work.

Yeah, we are mocking fs three levels down in bar, so that's why we have to set it up when testing foo

WAAAT???

If you write proper unit tests you should never have a need for this. So here are some techniques to consider:

  • test each module in isolation
  • make sure your modules are small enough and do only one thing
  • stub out dependencies directly instead of stubbing something inside your dependencies
  • if you are testing bar and bar calls foo.read and foo.read calls fs.readFile proceed as follows
    • do not stub out fs.readFile globally
    • instead stub out foo so you can control what foo.read returns without ever even hitting fs

OK, made it past the warnings and still feel like you need this? Read on then but you are on your own now, this is as far as I'll go ;)

Watch out for more warnings below.

Globally override require during module initialization

// foo.js
var bar = require('./bar');

module.exports = function() {
  bar();
}

// bar.js
var baz = require('./baz');

module.exports = function() {
  baz.method();
}

// baz.js
module.exports = {
  method: function() {
    console.info('hello');
  }
}

// test.js
var bazStub = {
  method: function() {
    console.info('goodbye');
  }
};
  
var stubs = {
  './baz': Object.assign(bazStub, {'@global': true}) 
};

var proxyquire = require('proxyquire');

var foo = proxyquire('./foo', stubs);
foo();  // 'goodbye' is printed to stdout

Be aware that when using global overrides any module initialization code will be re-executed for each require.

This is not normally the case since node.js caches the return value of require, however to make global overrides work , proxyquire bypasses the module cache. This may cause unexpected behaviour if a module's initialization causes side effects.

As an example consider this module which opens a file during its initialization:

var fs = require('fs')
  , C = require('C');

// will get executed twice
var file = fs.openSync('/tmp/foo.txt', 'w');

module.exports = function() {
  return new C(file);
};

The file at /tmp/foo.txt could be created and/or truncated more than once.

Why is proxyquire messing with my require cache?

Say you have a module, C, that you wish to stub. You require module A which contains require('B'). Module B in turn contains require('C'). If module B has already been required elsewhere then when module A receives the cached version of module B and proxyquire would have no opportunity to inject the stub for C.

Therefore when using the @global flag, proxyquire will bypass the require cache.

Globally override require during module runtime

Say you have a module that looks like this:

module.exports = function() {
  var d = require('d');
  d.method();
};

The invocation of require('d') will happen at runtime and not when the containing module is requested via require. If you want to globally override d above, use the @runtimeGlobal property:

var stubs = {
  'd': {
    method: function(val) {
      console.info('hello world');
    },
    '@runtimeGlobal': true
  }
};

This will cause module setup code to be re-executed just like @global, but with the difference that it will happen every time the module is requested via require at runtime as no module will ever be cached.

This can cause subtle bugs so if you can guarantee that your modules will not vary their require behaviour at runtime, use @global instead.

Configuring proxyquire by setting stub properties

Even if you want to override a module that exports a function directly, you can still set special properties like @global. You can use a named function or assign your stub function to a variable to add properties:

function foo () {}
proxyquire('./bar', {
  foo: Object.assign(foo, {'@global': true})
});

And if your stub is in a separate module where module.exports = foo:

var foostub = require('../stubs/foostub');
proxyquire('bar', {
  foo: Object.assign(foostub, {'@global': true})
});

Backwards Compatibility for proxyquire v0.3.x

Compatibility mode with proxyquire v0.3.x has been removed.

You should update your code to use the newer API but if you can't, pin the version of proxyquire in your package.json file to ~0.6 in order to continue using the older style.

Examples

We are testing foo which depends on bar:

// bar.js module
module.exports = {
    toAtm: function (val) { return  0.986923267 * val; }
};

// foo.js module
// requires bar which we will stub out in tests
var bar = require('./bar');
[ ... ]

Tests:

// foo-test.js module which is one folder below foo.js (e.g., in ./tests/)

/*
 *   Option a) Resolve and override in one step:
 */
var foo = proxyquire('../foo', {
  './bar': { toAtm: function (val) { return 0; /* wonder what happens now */ } }
});

// [ .. run some tests .. ]

/*
 *   Option b) Resolve with empty stub and add overrides later
 */
var barStub = { };

var foo =  proxyquire('../foo', { './bar': barStub });

// Add override
barStub.toAtm = function (val) { return 0; /* wonder what happens now */ };

[ .. run some tests .. ]

// Change override
barStub.toAtm = function (val) { return -1 * val; /* or now */ };

[ .. run some tests .. ]

// Resolve foo and override multiple of its dependencies in one step - oh my!
var foo = proxyquire('./foo', {
    './bar' : {
      toAtm: function (val) { return 0; /* wonder what happens now */ }
    }
  , path    : {
      extname: function (file) { return 'exterminate the name of ' + file; }
    }
});

More Examples

For more examples look inside the examples folder or look through the tests

Specific Examples:

More Repositories

1

doctoc

📜 Generates table of contents for markdown files inside local git repository. Links are compatible with anchors generated by github or other sites.
JavaScript
4,176
star
2

v8-perf

⏱️ Notes and resources related to v8 and thus Node.js performance
JavaScript
2,193
star
3

deoptigate

⏱️ Investigates v8/Node.js function deoptimizations.
JavaScript
1,148
star
4

brace

📔 browserify compatible version of the ace editor.
JavaScript
1,056
star
5

browserify-shim

📩 Makes CommonJS incompatible files browserifyable.
JavaScript
935
star
6

learnuv

Learn uv for fun and profit, a self guided workshop to the library that powers Node.js.
C
711
star
7

es6ify

browserify >=v2 transform to compile JavaScript.next (ES6) to JavaScript.current (ES5) on the fly.
JavaScript
595
star
8

visulator

A machine emulator that visualizes how each instruction is processed
JavaScript
381
star
9

exorcist

Externalizes the source map found inside a stream to an external .js.map file
JavaScript
332
star
10

parse-link-header

Parses a link header and returns paging information for each contained link.
JavaScript
298
star
11

libuv-dox

Documenting types and methods of libuv, mostly by reading 'uv.h'.
247
star
12

rid-examples

Examples showing how to use Rid in order to build Dart/Flutter apps integrated with Rust.
Dart
215
star
13

replpad

Pipes content of files to a node repl whenever they change to enable a highly interactive coding experience.
JavaScript
213
star
14

browserify-ftw

Converts an entire project that uses requirejs amd into on that uses nodejs common modules so it can be browserified.
JavaScript
188
star
15

cardinal

Syntax highlights JavaScript code with ANSI colors to be printed to the terminal.
JavaScript
175
star
16

turbolizer

Turbolizer tool from the v8 repository with added support to preload a profile
JavaScript
175
star
17

convert-source-map

Converts a source-map from/to different formats.
JavaScript
168
star
18

cpuprofilify

Converts output of various profiling/sampling tools to the .cpuprofile format so it can be loaded into Chrome DevTools.
JavaScript
167
star
19

flamegraph

Generates flamegraphs with Node.js or in the browser.
HTML
164
star
20

proxyquireify

browserify >= v2 version of proxyquire. Mocks out browserify's require to allow stubbing out dependencies while testing.
JavaScript
153
star
21

batufo

UFO mutli-player game using Flutter.
Dart
152
star
22

spok

Checks a given object against a given specification to keep you from writing boilerplate tests.
TypeScript
147
star
23

v8-flags

Configures v8 flags at runtime.
C
119
star
24

wasm2js

Compile WebAssembly .wasm files to a commonjs module.
JavaScript
110
star
25

browserify-markdown-editor

A demo showing how to build a markdown editor with browserify and marked.
JavaScript
91
star
26

combine-source-map

Add source maps of multiple files, offset them and then combine them into one source map.
JavaScript
78
star
27

nad

Node Addon Developer, a tool to inject your addon code into a copy of the node codebase in order to integrate with IDEs and debuggers easily.
JavaScript
76
star
28

irish-pub

Feel like npm is drunk or maybe you are and want to verify what gets published via `npm publish`? irish-pub has you covered.
JavaScript
69
star
29

hypernal

Renders terminal output as html to simplify reusing server side modules in the browser.
JavaScript
64
star
30

rid

Rust integrated Dart framework providing an easy way to build Flutter apps with Rust.
Rust
64
star
31

exposify

browserify transform that exposes globals added via a script tag as modules so they can be required.
JavaScript
63
star
32

nif

node --inspect a file and open devtool url in chrome via chrome-cli.
JavaScript
59
star
33

active-handles

Prints out information about the process's active handles, including function source and location
JavaScript
58
star
34

doctoc-web

This is the source of the DocToc web application.
JavaScript
56
star
35

traceviewify

Converts .cpuprofile format to trace viewer JSON object format to allow analysing the data in chrome://tracing.
JavaScript
55
star
36

readline-vim

Adds vim bindings to nodejs readline.
JavaScript
55
star
37

docme

Generates github compatible API documentation from your project's jsdocs and adds them to your Readme.
JavaScript
54
star
38

bunyan-format

Writable stream that formats bunyan records that are piped into it
JavaScript
51
star
39

wicked

Generates github wiki compatible API documentation from your project's jsdocs and adds them to your wiki.
JavaScript
49
star
40

lldb-jbt

Adds JavaScript symbols to lldb stack traces
Python
48
star
41

phe

Poker hand evaluator
JavaScript
47
star
42

d3-gauge

Gauge visualization built on top of d3.
CSS
45
star
43

dev-null

/dev/null for node streams
JavaScript
43
star
44

WebToInk

Downloads and converts a properly set up Html book or a blog into mobi format
Haskell
40
star
45

docmac

Install docker on Mac including VirtualBox and boot2docker dependencies with one simple command.
Shell
39
star
46

stack-mapper

Initialize it with a source map, then feed it error stacks to have the trace locations mapped to the original files.
JavaScript
39
star
47

stream-viz

Visualizes streams in the browser.
JavaScript
37
star
48

dotfiles

My vim and bash related dotfiles.
Shell
36
star
49

iojs-inspect-entire-stack

Demonstrating how to inspect the entire io.js stack
JavaScript
36
star
50

hermit

Prints html in the terminal using colors and simple layout to reflect the document structure.
JavaScript
36
star
51

v8-map-processor

Processes and visualizes maps (aka hidden classes) created by v8 during execution.
HTML
35
star
52

mold-source-map

Mold a source map that is almost perfect for you into one that is.
JavaScript
35
star
53

bromote

Tool to setup and require remote scripts with browserify.
JavaScript
35
star
54

log.h

Minimal yet colorful logging lib.
C
34
star
55

inline-source-map

Adds source mappings and base64 encodes them, so they can be inlined in your generated file.
JavaScript
34
star
56

testlingify

Adds github hooks and browser config for testling.
JavaScript
33
star
57

browserify-swap

A transform that swaps out modules according to a config in your package.json selected via an environment variable.
JavaScript
32
star
58

v8-profiling

Exploring how to hook into the various v8 profilers
C++
32
star
59

scriptie-talkie

Makes your code tell you what the intermediate results are when executing a script.
JavaScript
31
star
60

ee.c

EventEmitter in C.
C
30
star
61

resolve-bin

Resolves the full path to the bin file of a given package by inspecting the \"bin\" field in its package.json.
JavaScript
30
star
62

node-syntaxhighlighter

Node friendly version of Alex Gorbachev's great SyntaxHighlighter.
CSS
29
star
63

v8-runtime-functions

Exposing and documenting v8 runtime functions.
JavaScript
27
star
64

hyperwatch

Streams server side log messages to the browser and renders them inside your page.
JavaScript
27
star
65

sass-resolve

Resolves all sass files in current project and all dependencies to create one sass file which includes them all.
JavaScript
26
star
66

ansicolors

Functions that surround a string with ansicolor codes so it prints in color.
JavaScript
26
star
67

dockerify

Prepares any tarball containing a project so that a docker image can be built from it.
JavaScript
26
star
68

spinup

Spins up multiple versions of your app, each in its own docker container
JavaScript
25
star
69

redeyed

Takes JavaScript code, along with a config and returns the original code with tokens wrapped and/or replaced as configured.
JavaScript
25
star
70

anchor-markdown-header

Generates an anchor for a markdown header.
JavaScript
25
star
71

nasmx

The NASMX Project (manually maintained mirror) Documentation: https://thlorenz.github.io/nasmx
Assembly
25
star
72

find-parent-dir

Finds the first parent directory that contains a given file or directory.
JavaScript
24
star
73

dox

Notes and cheat sheets on various topics
DTrace
23
star
74

benchgraph

Runs {io,node}.js benchmarks and generates pretty graphs
JavaScript
22
star
75

kebab

Half queue half pubsub. Super small (< 30 loc) and simple queue that supports subscribers.
JavaScript
22
star
76

pong.asm

pong game written in assembly for i386 (32-bit) architecture.
Assembly
22
star
77

linuxasmtools

This package is part of AsmTools (a collection of programs for assembler development on Linux X86 cpu's.)
Assembly
22
star
78

peacock

JavaScript syntax highlighter that generates pygments compatible html and therefore supports pygments styles.
CSS
22
star
79

talks

Numerous talks I gave at meetups and conferences some based on reveal.js.
HTML
20
star
80

valiquire

Validates that all require statements in a project point to an existing path and are correctly cased.
JavaScript
20
star
81

prange

Parses poker hand range short notation into a range array.
JavaScript
19
star
82

jsdoc-githubify

A transform that adapts html files generated with jsdoc to be rendered in a github wiki or readme.
JavaScript
19
star
83

chromium-remote-debugging-proxy

A proxy that sits in between a chromium devtools frontend and the remote chromium being debugged and logs requests, responses and websocket messages that are exchanged.
JavaScript
19
star
84

ocat

Inspect an object various ways in order to easily generate test cases.
JavaScript
17
star
85

v8-sandbox

C++
17
star
86

hhp

Poker HandHistory Parser
JavaScript
16
star
87

node-traceur

Mirror of experimental ES6 to ES5 compiler that is kept in sync with code on google.
JavaScript
16
star
88

v8-ic-processor

Processes and visualizes IC (inline cache) information collected for functions in your application
HTML
16
star
89

pec

Poker equity calculator. Compares two combos or one combo against a range to compute winning equity.
JavaScript
16
star
90

floodgate

Throttles a stream to pass one value per given interval.
JavaScript
16
star
91

level-dump

Dumps all values and/or keys of a level db or a sublevel to the console.
JavaScript
15
star
92

tap-stream

Taps a nodejs stream and logs the data that's coming through
JavaScript
14
star
93

parse-key

Parses strings into key objects of the same format as the ones emitted by nodejs readline.
JavaScript
14
star
94

dockops

docker convenience functions on top of dockerode
JavaScript
14
star
95

nf-rated

Store and process Netflix movies including IMDB rating.
Rust
14
star
96

lib.asm

Collection of assembly routines in one place to facilitate reuse.
Assembly
13
star
97

sql-escape-string

Simple SQL string escape.
JavaScript
13
star
98

caching-coffeeify

A coffeeify version that caches previously compiled coffee-script to optimize the coffee-script compilation step.
JavaScript
13
star
99

cathode

Example for react server side rendering without the fluff
JavaScript
11
star
100

dog

Developer blOGgin Engine, markdown based, made to be simple and fast, yet feature rich.
JavaScript
11
star