Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
proxyquire
Advanced tools
Proxies nodejs require in order to allow overriding dependencies during testing.
Proxyquire is a powerful tool for stubbing and mocking dependencies in Node.js unit tests. It allows you to override dependencies during testing without modifying the actual code, making it easier to isolate and test individual modules.
Basic Dependency Override
This feature allows you to override a dependency with a mock implementation. In this example, the './dependency' module's 'myFunction' is replaced with a mock function that returns 'mocked value'.
const proxyquire = require('proxyquire');
const myModule = proxyquire('./myModule', {
'./dependency': { myFunction: () => 'mocked value' }
});
console.log(myModule.useDependency()); // Outputs: 'mocked value'
Override Multiple Dependencies
This feature allows you to override multiple dependencies at once. In this example, both './dependency1' and './dependency2' are replaced with mock implementations.
const proxyquire = require('proxyquire');
const myModule = proxyquire('./myModule', {
'./dependency1': { myFunction1: () => 'mocked value 1' },
'./dependency2': { myFunction2: () => 'mocked value 2' }
});
console.log(myModule.useDependencies()); // Outputs: 'mocked value 1 and mocked value 2'
Conditional Overrides
This feature allows you to conditionally override dependencies based on certain conditions, such as environment variables. In this example, the './dependency' module is only mocked if the TEST_ENV environment variable is set.
const proxyquire = require('proxyquire');
const myModule = proxyquire('./myModule', {
'./dependency': process.env.TEST_ENV ? { myFunction: () => 'mocked value' } : require('./dependency')
});
console.log(myModule.useDependency()); // Outputs: 'mocked value' if TEST_ENV is set, otherwise the real value
Sinon is a popular library for creating spies, stubs, and mocks in JavaScript. Unlike Proxyquire, which focuses on overriding dependencies, Sinon provides a more comprehensive set of tools for creating test doubles and verifying interactions.
Rewire is another library that allows you to modify the behavior of modules during testing. It provides a similar functionality to Proxyquire but with a different API. Rewire allows you to access private variables and functions within a module, which can be useful for more fine-grained control.
Mock-require is a simpler alternative to Proxyquire that allows you to mock Node.js modules. It provides a straightforward API for replacing modules with mock implementations, but it lacks some of the advanced features of Proxyquire.
Proxies nodejs's require in order to make overriding dependencies during testing easy while staying totally unobstrusive.
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').setup()
, assert = require('assert');
// no overrides yet, so path.extname behaves normally
var foo = proxyquire.require('./foo');
assert.equal(foo.extnameAllCaps('file.txt'), '.TXT');
// override path.extname
proxyquire({
path: { extname: function (file) { return 'Exterminate, exterminate the ' + file; } }
});
// path.extname now behaves as we told it to
foo = proxyquire.require('./foo');
assert.equal(foo.extnameAllCaps('file.txt'), 'EXTERMINATE, EXTERMINATE THE FILE.TXT');
// path.basename and all other path module methods still function as before
assert.equal(foo.basenameAllCaps('/a/b/file.txt'), 'FILE.TXT');
Table of Contents generated with DocToc
npm install proxyquire
Three simple steps to override require in your tests:
var proxyquire = require('proxyquire').setup();
on top level of your test fileproxyquire({ path: { extname: function () { return 'meh'; } });
in your testproxyquire.require(..)
the module you want to test and excercise its methodsAlternatively if you are worried about test speed and/or are testing very large modules:
var require = require('proxyquire');
on top of any module whose requires you want to be able to controlrequire
in order to require the module you want to test and excercise its methodsvar proxyquire = require('proxyquire').setup();
proxyquire.require(..)
proxyquire.require(String [, String])
Works the same as nodejs's require
while preparing the to be tested module to have its dependencies overridden.
proxyquire.require
injects a require
override before passing it on to nodejs's require
__dirname
of test file, but ideally this would be done via proxyquire.setup()
proxyquire.reset()
Useful if you want to entirely start over in overriding dependencies.
proxyquire.add(Object)
Adds overrides for given methods in particular modules.
Example:
proxyquire.add({
'./module1': {
prop: /* override */
, func: function () { /* override */ }
}
, module2: {
prop: /* override */
, func: function () { /* override */ }
, __proxyquire: { strict: true }
}
});
'./module1'
)
__proxyquire
property allows to further configure overrides. In the case of
module2 it is configured to be strict
see strict vs. non-strict
overridesproxyquire(Object)
A shortcut which calls proxyquire.reset()
and then proxyquire.add(Object)
proxyquire.del(String | Object)
Removes overrides and replaces them with method of the real module unless it was overridden using strict mode.
Examples:
Assume path.extname
and path.basename
were overridden previously.
Remove all path
module overrides:
proxyquire.del('path');
Remove only path.extname
override:
proxyquire.del({ path: 'extname' });
Explicitly remove path.extname
and path.basename
overrides. (In this case
this has the same effect as overriding entire path
module):
proxyquire.del({ path: [ 'extname', 'basename' ] });
proxyquire's API supports chaining of method calls during setup.
Things like:
proxyquire
.reset()
.add({
path: { extname: function (x) { return 'what?'; }
})
.add({
fs: { realpath: function (x, y) { return 'no really, what?'; }
})
.del('path')
;
are perfectly legal. Yes I know this example is totally contrived, but it shows lots of possibilities in one shot ;) .
Controls what happens when a function that wasn't overridden (added) via proxyquire is called.
In non-strict mode proxyquire will call the method with the same name on the 'real' module.
In strict mode proxyquire will fail with has no method ...
exception
Examples:
proxyquire.add({
path: { extname: function (x) { return 'what?'; }
})
require('path').basename('/a/b/c.txt') // returns 'c.txt'
proxyquire.add({
path: { extname: function (x) { return 'what?'; }
, __proxyquire: { strict: true }
})
require('path').basename('/a/b/c.txt') // will throw an error
For more examples look inside the examples folder or look through the tests
FAQs
Proxies nodejs require in order to allow overriding dependencies during testing.
The npm package proxyquire receives a total of 416,888 weekly downloads. As such, proxyquire popularity was classified as popular.
We found that proxyquire demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.