Giter VIP home page Giter VIP logo

proxyquire's Issues

Cyclic Dependencies

I am running into an issue that probably many ppl have who use express along with proxyquire, since express projects usually have a cyclic dependency in their setup. But this issue could really occur in any project with 2 files requiring each other. For demonstration purposes, I gonna sketch out an example with express (sorry for making this so verbatim and if I go through some very basic express setup here):

Express projects usually have an app.js at the top of the dependency chain that registers some middleware and the routes the server should listen to. Usually ppl attach all their routes in a different file to keep the app.js short.

// app.js
const app = module.exports = express()
const server = http.createServer(app)

// ... here go some pre-routing middleware
require('./routes/webroutes')
// ... then some post-routing middleware

// finally the server is started
server.listen()

The webroutes.js simply requires the app.js singleton and attaches some routes to it. Note that at the point of time at which webroutes.js executes app.js is not fully configured yet (in fact, only the first line of app.js has been executed yet).

// routes/webroutes.js
var app = require('../app)
app.get('/v0-1-0/hello/world', helloController.sayWorld)

To complete the picture, here the controller that depends on modules I would like to sub out, fs for example.

// controllers/helloController.js
var fs = require('fs')
exports.sayWorld = function() {
  return fs.mkdirSync('/hello/world')
}

I now would like to create a functional test that starts the server in its entirety. The only way I can get this sort-of working is this:

// test/app.js
var stubbedHelloController = proxyquire('../routes/webroutes', {
  'fs': myFsStub
})

// get a stubbed app and prevent that the unstubbed app instance gets any routes attached
var stubbedApp = proxyquire('../app', {
  './routes/webroutes': {}
})

// then attach the routes to the stubbed app
var subbedWebroute = proxyquire('../routes/webroutes', {
  '../app': stubbedApp,
  '../controllers/helloController': stubbedHelloController
})

This really feels like a hack and there are other cyclic dependencies that cannot be bypassed like this. In the above example, the routes are registered after the post-routing middleware. My question is, is there any way to handle cyclic dependencies properly? Global mocking as suggested in issue #12 might resolve this issue as long as one of the participating modules in the cycle are not the ones you wanna mock. Any suggestions?

undefined hasOwnProperty?

I'm a little baffled by this one, because hasOwnProperty is a part of node core. Using node-v0.12.7 and proxyquire-1.6.0.

/Users/kevin/Projects/omnisearch/node_modules/proxyquire/lib/proxyquire.js:117
    if (hasOwnProperty.call(stubs[key], '@global')) {
                       ^
TypeError: Cannot convert undefined or null to object
    at hasOwnProperty (native)
    at Proxyquire.load (/Users/kevin/Projects/omnisearch/node_modules/proxyquire/lib/proxyquire.js:117:24)

How to reset/un-mock the mocked dependency in proxyquire?

File structure:

.
|____lib
| |____bar.js
| |____baz.js
| |____foo.js
|____test
| |____bar.js
| |____baz.js
| |____foo.js

Use case:

With respect to the above file structure, ./lib/foo.js requires ./lib/bar.js, ./lib/bar.js requires ./lib/baz.js.


While unit testing ./lib/foo.js via ./test/foo.js, I would like to mock ./lib/bar.js, so that, I am only concerned with ./lib/foo.js.
Once the tests in ./test/foo.js are over I would like to reset/un-mock ./lib/bar.js.

While unit testing ./lib/bar.js via ./test/bar.js, I would like to mock ./lib/baz.js, so that, I am only concerned with ./lib/baz.js.
Once the tests in ./test/foo.js are over I would like to reset/un-mock ./lib/baz.js.

So on and so forth.


Or in other words, I would like to mock the dependencies and reset as and when required, in the test file.

Most likely mocking several times in the test file and reseting a after all the test are over in a test file.

Or may be I can control the local mock, with some file level closure variables


Looks like mockery addresses my use-case, mainly reset/un-mock the mocked dependency.

How to achieve the same in proxyquire?

Multiple proxyquires of the same module returns undefined in all responses but the first one

I'm stubing a dependency using proxyquire.
In these tests, I'm using mocha and chai, like:

var proxyquire =  require('proxyquire').noPreserveCache();
var expect = require('chai').expect;
var done = require('chai').done;
var Q = require('q');
var objJSON = require('../resources/objJSON');

describe("Service", function() {

    describe("MyService", function() {

        describe("findAll() function", function() {

            it("should call db methods", function() {

                var myMockedService1 = proxyquire.load('../../app/services/myService', {
                    './db': {
                        select: function (field) {
                            return {
                                table: function (table) {
                                    var deferred = Q.defer();
                                    deferred.resolve(objJSON);
                                    return deferred.promise;
                                }
                            };
                        }
                    }
                });

                // myMockedService is now correctly mocked
                // BUT if I do another proxyquire just like the one done above, I get undefined as answer !!

                myMockedService.findAll().then(function(obj) {
                    expect(JSON.stringify(obj)).equal(JSON.stringify(objJSON));
                    done();
                });
            });
        });
    });
});

The first proxyquire works gret, but if I repeat another one next to the first one, it returns undefined as answer.
Could anyone point me if I'm missing some initialization of proxyquire if I'll require the same module multiple times? This blocks the tests by now. Thanks !!

Global overrides

This was touched on in #22 and #16, but would it be possible for proxyquire to override require globally rather than only one level deep?

The API could look similar to no-call-through:

var foo = proxyquire('./foo', {
  path: {
      extname: function (file) { ... }
    , '@noCallThru': true
    , '@global': true  //  <-- Makes this override apply everywhere
  }
});

My use case is a little outside of proxyquire's usual remit. I'm writing a workshopper based tutorial where the user submits a solution, A, to a problem. A requires B which requires C, but the interactions with C are what dictates whether the solution is correct or not.

I proxyquire the solution with stubs for C, so if it were to override require globally then asserting on the correct interactions becomes really simple.

proxyquire won't catch dynamic requires

It's as if proxyquire won't stay active to catch later requires, or it is designed like that because it can't handle those.

I surely hope to get an explanation :)

Paths passed to proxyquire must be relative to the file that actually required proxyquire, not to the currently executing test

In a lot of our tests we want to centralize test bootstrapping so we've put loading of proxyquire into a centralized bootstrap file. So in a given test file this ends up looking like this (coffeescript):

{proxyquire} = require '../helpers/bootstrap'

When doing this , all of my calls to proxyquire(...) need to have the path relative to the bootstrap.coffee file and not the test file.

To test this, I removed the requiring of proxyquire from the bootstrap file into the test file itself and paths worked as expected. I also moved the bootstrap file to a new directory and confirmed that I had to change all of my relative paths passed to the proxyquire call to be relative to the new bootstrap.

Any ideas as to why this might be happening or if there's a possible fix?

Browserify Compatibility

We're using browserify to share our server side code with the client.
Our unit tests heavily use proxyquire to mock out module dependencies.

Of course we'd like to also run our unit tests in browsers, to make sure everything is working correctly. When attempting to browserify the unit tests and run them in the client, I ran into issues related to require.cache and require.resolve in https://github.com/thlorenz/proxyquire/blob/master/index.js#L7 since they are undefined.
I'd really like to get this working, so I'm wondering what needs to be done to make proxyquire compatible with browserify. Since you're quite active in the browserify project, maybe you already have an idea, or can immediately tell me it's not possible.

I'd love to help out with this.

Support for Webpack?

Hello,

Thanks for this great library! I wonder whether there are any plans to support also Webpack in addition to Browserify. How large job is it to add support for it?

Thank you!

Proxyquire cannot stub non-object imports

Say I have a module options.coffee...

module.exports = 'foo'

I want to stub it for a test...

describe '/lib/anotherModule', ->
  imports = {}
  before ->
    imports['./options'] = 'bar'
  beforeEach ->
    thing = proxyquire "#{process.cwd()}/lib/thing", imports
  it 'should be defined', ->
    thing.should.exist

This will fail in the before block, because Proxyquire cannot mock non-object exports. The error is:

    TypeError: Object.keys called on non-object
    at Function.keys (native)
    at fillMissingKeys (/Users/pete/kinvey/projects/cli/node_modules/proxyquire/lib/proxyquire.js:12:10)
    at Proxyquire._require (/Users/pete/kinvey/projects/cli/node_modules/proxyquire/lib/proxyquire.js:143:7)
    at require (module.js:380:17)

Globally override a module that returns a function

I know that you can set '@global': true in the stubs for modules that are objects, but how do you do it for modules that return functions. For example:

// main.js
var Deep = require('./deep');

var instance = new Deep();
instance.run();

module.exports = instance;
// deep.js
var deepest = require('./deepest')('My Name');

function Deep() {
}

Deep.prototype = {
  run: function() {
    deepest.baz();
  }
};

module.exports = new Deep();
// deepest.js
function Deepest(name) {
  return {
    baz: function() {
      console.log(name);
    }
  };
}

module.exports = Deepest;

Deepest returns a function that I need to mock out, but since it is used inside of Deep, I have to use @global.

If deepest was exporting the inner object instead of the wrapping function, I could do this:

var main = proxyquire('./main.js', {
  './deepest': {
    '@global': true,
    'baz: function() {}
  }
}

But since deepest returns a function, my understanding is that I have to mock it like this:

var main = proxyquire('./main.js', {
  './deepest': function() {
    return {
      baz: function() {
        console.log('mocked');
      }
    }
  }
}

But I can no longer set '@global' on the mock object. Right? How should I handle this? This situation has arisen because of the api design of a third party module so I sadly can't really restructure these calls.

Mocking internal class

Hello
I'm trying need to mock third party class (
This is code to be tested:

/myclas.js/
tps = require('tps');
myClass.prototype.myFunction(){
tpsInstance = tps.InClass();
.....
};
Unit test code

tps = proxyquire('myclass',{tps:tpsStub});
....

/tpsStub/

function tpsStub() {
this.InClass() = function(){
.....
}
}
When called tpsInstance = tps.InClass(); (from code above) - tpsStub created but trying to instantiate REAL InClass class The question: how can I create stub for InClass ? What was wrong in code above?
Thanks in advance

Special handling for transpiled ES6 modules?

Currently, if you want to stub a transpiled es6 module, you need to do something like this:

const mod = proxyquire('./path/to/mod', {
  '../dep': {
    __esModule: true,
    doSomething: function() { /* ... */ },
  },
});

The __esModule is used by tools like Babel and Traceur to deal with module format interop. It would be convenient if proxyquire automatically added it to the stub if present in the original.

Recursive Overrides

I'm working on a way of tracking what files various compilers (like CoffeeScript, Jade, and Stylus) rely on when compiling, to make a better asset-graph for roots. For example, if a Jade file has the line include _partial, when it is compiling it will read _partial.jade, and whenever _partial.jade is modified, the original Jade file will need to be recompiled.

In order to track what files get read by the compiler, I am trying to stub fs so that readFile() and readFileSync() log what files are read. However, these compilers are made up of several modules, so I need a way to override fs throughout the entire compiler, without knowing any of the names of the compiler modules (since we aim to support ~30 languages, it wouldn't be easy to study each compiler).

Do you have any idea on how to do this?

How to stub out the filesystem many modules deep

I'm trying to use fe to run jasmine on my browserified code:

var jasmine = proxyquire('gulp-jasmine', { 'fs': fe.fs })

gulp.src('./test/*')                                                                 
  .pipe(browserify(...))                                                                                  
  .pipe(                                                                             
    es.map(function (file, callback) {                                               
      var folder = fe.instance().directory(path.dirname(file.path))                  
      fe.instance().file(folder, path.basename(file.path))                           
      callback(null, file)                                                           
    })                                                                               
  )                                                                                  
  .pipe(jasmine())                                                                                  

But jasmine still tests the unbrowserified code! It seems like proxyquire is only replacing fs one level deep. I need everything that gulp-jasmine requires to also use the stubbed fs module.

Proxyquire does not override dependencies for one module only.

I want to test one module that makes use of the fs module.
So I stubbed out fs.existsSync and everything was working nicely. That was until I got to the part where I also needed to create a stub for fs.readFileSync.
Suddenly it all broke. I took me a while to realize that that's because I import another module that also uses fs.readFileSync.
I had also proxyquired that dependency so I didn't expect that.
What happened is that even though I had a complete mock for the module, proxyquire still loaded it.

So my question is, is there a way to tell proxyquire to either only replace the dependency once, in the module I actually requested, or if I can keep it from trying to load the dependency at all if I have a complete mock and don't just need to stub it.
@noCallThru does not work for this. It still loads the module, calls fs.readFileSync and then dies.

Request: ability to stub non-existent modules

Often, your dev environment does not match your production environment. Some custom system modules cannot be installed on my local laptop dev machine, and it would be extremely handy to be able to stub modules that are otherwise not available on the system.

Perhaps this is via an explicit flag, such that you have to proactively specify it, so as not to introduce typo errors.

A simple try/catch around the require, and then returning just the stub if require cannot find the module should suffice.

Thanks!

fail for non-existing path?

When I stub a path that does not exist, no error is thrown (correct me if I'm wrong). To prevent confusion, It would be very helpful to not silently accept ineffective stubs.

noPreserveCache doesn't seem to work in 1.0.0

Somewhere between 0.6.0 and 1.0.0, the noPreserveCache function no longer appears to be doing what the documentation says it will do.

I have a situation similar to the one described in #25โ€” Imagine I have the following files:

foo.js:

exports.bar = function() {
  return 'real';
};

usesFoo.js:

var foo = require('foo');
exports.baz = function() {
  return foo.bar() + ' thing';
};

usesFooUnitTest.js:

var proxyquire = require('proxyquire').noPreserveCache();
var usesFoo = proxyquire('usesFoo', {
  'foo': {
    bar: function() {
      return 'fake';
    }
  }
});
expect(usesFoo.baz()).to.equal('fake thing'); // test passes

integrationTest.js:

var usesFoo = require('usesFoo');
expect(usesFoo.baz()).to.equal('real thing'); // test fails! returns 'fake thing'

Since I have a grunt build that runs unit tests immediately followed by integration tests, my build fails on the integration tests as shown above. If I just run integration tests in isolation, they pass just fine. Also, if I change my package.json to use proxyquire 0.6.0, my build also passes.

Obviously understanding that any 0.x.x version may not yet have a hardened API... I'm wondering: was this an intended breaking change when moving to 1.0, and the documentation is just out of date? Or is this a regression? If it's the latter, is there a suggested workaround?

Thanks!

Proxyquire Failing to load stubbed content

Hi,

I really like using proxy quire but I have been running into a strange issue. When i stub a required object, the original is loaded. If i npm remove the object it throws 'Cannot find module'. So i created the smallest use case for this.

File: demo.js

var _ = require('lodash');

module.exports.test1 = function() {
  return _.sum([1, 2]);
};

var doesNotExist = require('doesNotExist');

module.exports.test2 = function() {
  return doesNotExist.test();
};

Test Case: demo.spec.js

var proxyquire = require('proxyquire'),
  chai = require('chai'),
  expect = chai.expect;

function setup() {
  return proxyquire('./demo', {
    lodash: {
      sum: function(arr) {
        var total = 0;
        arr.forEach(function(num) {
          total += num;
        });
        return total + 'test';
      }
    },
    doesNotExist: {
      test: function() {
        return true;
      }
    }
  })
}

describe('Test Proxyquire', function() {
  it('should handle lodash override correctly', function() {
    var test = setup();
    expect(test.test1([1, 2])).to.be.equal('3test')
  });

  it('should handle doesNotExist correctly', function() {
    var test = setup();
    expect(test.test2()).to.be.equal('proxy worked');
  });
});

run

npm install mocha lodash chai proxyquire

launch test with

node node_modules/mocha/bin/_mocha --reporter spec demo.spec.js

The first test will pass if you remove the 'var doesNotExist = require('doesNotExist');' line. However proxyquire doesn't seem to be able to override a module that isn't installed.

Is this the intended functionality? Did I miss some documentation?

Possible to stub constructors?

For example-

In my 'email.js' I have:

var mandrill = require('mandrill-api/mandrill');
var mandrill_client = new mandrill.Mandrill('API_KEY_HERE');

exports.sendTemplate = function(templateName, to, variables, callback) {

    console.log('mandrill_client === ', mandrill_client)

    var message = {
        //omitted for brevity
    };

    mandrill_client.messages.sendTemplate({
        template_name: templateName,
        template_content: [],
        message: message,
    }, function(result) {
        //... do something
        return callback();
    }, function(err) {
        //...
    });
}

Then, in my test, I want to stub out mandrill, so that when a new mandrill_client is created, it gets my stubbed version, ultimately with a sinon.spy on mandrill_client.messages.sendTemplate

//not sure what mandrillStub should be??

email = proxyquire('../../../app/helpers/email', {
    'mandrill-api/mandrill': mandrillStub
});

Is this possible?

Problems mocking fs module

I use proxyquire a lot while testing and all is working fine, except when I try to mock the fs module. The shortest example:

var fsStub, proxyquire, subject;
proxyquire = require('proxyquire');
fsStub = null;

subject = proxyquire('./lib/worker/update', {
  fs: fsStub
});

Leads to:

/private/tmp/t/node_modules/proxyquire/lib/proxyquire.js:147
      throw moduleNotFoundError(path);
            ^
Error: Cannot find module 'fs'
    at createNotFoundError (/private/tmp/t/node_modules/proxyquire/node_modules/module-not-found-error/index.js:4:13)
    at Proxyquire._require (/private/tmp/t/node_modules/proxyquire/lib/proxyquire.js:147:13)
    at require (module.js:384:17)
    at Object.<anonymous> (/private/tmp/t/lib/worker/update.js:1:72)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Object.require.extensions.(anonymous function) [as .js] (/private/tmp/t/node_modules/proxyquire/lib/proxyquire.js:243:43)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)

Am I missing something here?

proxyquire: v1.7.1
nodejs: v0.12.7

Stub not overriding original

Hi,

I realize I'm probably doing something wrong, but I've tried several things and no matter what I do I can't get my stubbed function to run within my module under test. I have no problems when experimenting with variations of provided samples including the sinon one. I'm hoping a more experienced pair of eyes could help me out a little.

Module under test with nano, the couchdb module dependency I want to mock.

var async = require('async');
var db = require('nano')('http://localhost:5984/mydb');

module.exports.getDocs = function(docs, callback){
  // some logic
  async.map(docs, function(doc, cb) {
    db.get(doc, function(err, body) {
      cb(err, body);
    });
  }, function(err, results) {
    if (err) {
      callback(err, null);
    } else {
      callback(null, results);
    }
  });
};

Test using proxyquire and sinon.

var proxyquire = require('proxyquire');
var sinon = require('sinon');
var db = require('nano')('http://localhost:5984/mydb');
var couchdb; // import using proxy below

describe('CouchDB document model', function(){
  var getStub;

  before(function () {
    getStub = sinon.stub(db, 'get');
    couchdb = proxyquire('../../../app/models/couchdb', { db: {get: getStub} });
    getStub.yields({'some': 'data'});
  });

  after(function () {
    db.get.restore();
  });

  describe('getDocs function', function(){
    it('should use fake couchdb data', function(done) {
      couchdb.getDocs(docs, function(err, body) {
        // Getting body with data from real CouchDB, i.e. original db.get is called
        done();
      });
    });
  });

});

Impossible to stub non-existing module expecting to return a function.

Hi, I have a factory that I wish to test some functionality of.

This factory method returns new function() instances.

Therefore I wish to stub something along the line of:

proxyquire('factorypath': {
'factorypath/testFunc' : testFunc
});

But it won't allow it. So I thought I'd set '@noCallThru', but that is not possible when a module is supposed to return just a function.

Or am I missing something here?

Working with relative paths

Writing the following seems impossible:

var log = proxyquire('./log', {"../config", {}});

Is there something wrong in this?
Thanks for your help.

Windows 7 not supported

Hey, great work - this is (almost) exactly what I needed for my tests :)
Unfortunately though i tend to develop on multiple platforms including windows 7. When I try to use proxyquire on windows I get the following error:

    Error: Cannot find module 'V:GitHubTestRunner
ode_modulesproxyquireproxyquire.js'
      at Function.Module._resolveFilename (module.js:338:15)
      at Function.Module._load (module.js:280:25)
      at Module.require (module.js:362:17)
      at require (C:\Users\PHALLI~1\AppData\Local\Temp\mocha.js@0:1:211)
      at new module.exports (C:\Users\PHALLI~1\AppData\Local\Temp\mocha.js@0:2:15)
      at Context.<anonymous> (V:\GitHub\TestRunner\test\grunt\mocha.test.js:23:19)
      at Test.Runnable.run (V:\GitHub\TestRunner\node_modules\mocha\lib\runnable.js:187:15)
      at Runner.runTest (V:\GitHub\TestRunner\node_modules\mocha\lib\runner.js:307:10)
      at Runner.runTests.next (V:\GitHub\TestRunner\node_modules\mocha\lib\runner.js:353:12)
      at next (V:\GitHub\TestRunner\node_modules\mocha\lib\runner.js:235:14)

from a call like this:

    var MochaTask = proxyquire.resolve('../../src/grunt/mocha.js', __dirname, {
            'mocha': mochaMock(),
            'module': new ModuleMock()
        });

looks like it is munging the path separators.

BTW, using proxyquire 0.3.2

Example with express+selenium

Hi,

I got referred to proxyquire by Steve Cresswell, the guy behind BDD framework Yadda.

I'm liking the look of proxyquire.

As a relative noobie to Javascript and nodejs/express - I'm hoping for a leg up with an example of using proxyquire with express+node+selenium to use with my Yadda tests.

I'm struggling to see how we can bootstrap the fake within this environment.

The web page is calling into the route in express, I don't want to fake the route code, that still needs to execute. The route code calls a service and I want to fake an error coming out of the service call.

Cheers,

Nick

Proxyquire seems to break stack traces

I'm trying to mock the chalk module for ESLint tests to be able to test the stylish formatter:
https://github.com/eslint/eslint/blob/master/lib/formatters/stylish.js
Unfortunately, this seems to break stack traces which makes it harder to find where the problem is. I'm mocking chalk red & yellow methods via:

var chalkStub = Object.create(chalk),
    counters = {};

["yellow", "red"].forEach(function (color) {
    counters[color] = {
        regular: 0,
        bold: 0
    };
    Object.defineProperty(chalkStub, color, {
        value: function (str) {
            console.log("trace for color", color);
            console.trace();
            console.log("");
            var colored = chalk[color](str);
            counters[color].regular++;
            return colored;
        },
        writable: true
    });
    chalkStub[color].bold = function (str) {
        console.log("trace for bold color", color);
        console.trace();
        console.log("");
        var colored = chalk[color].bold(str);
        counters[color].bold++;
        return colored;
    };
});

var formatter = proxyquire("../../../lib/formatters/stylish", {chalk: chalkStub});

In a different part of the file, I have:

var result = formatter(code, config);

This should invoke the stylish formatter & show me what exactly led to invocation of the yellow method but I get this trace instead:

trace for bold color yellow
Trace
    at Function.chalkStub.(anonymous function).bold (/Users/mgol/Documents/projects/public/eslint/tests/lib/formatters/stylish.js:35:17)
    at module.exports (/Users/mgol/Documents/projects/public/eslint/lib/formatters/stylish.js:9:3011)
    at Context.<anonymous> (/Users/mgol/Documents/projects/public/eslint/tests/lib/formatters/stylish.js:72:26)
    at Test.Runnable.run (/Users/mgol/Documents/projects/public/eslint/node_modules/mocha/lib/runnable.js:211:32)
    at Runner.runTest (/Users/mgol/Documents/projects/public/eslint/node_modules/mocha/lib/runner.js:358:10)
    at /Users/mgol/Documents/projects/public/eslint/node_modules/mocha/lib/runner.js:404:12
    at next (/Users/mgol/Documents/projects/public/eslint/node_modules/mocha/lib/runner.js:284:14)
    at /Users/mgol/Documents/projects/public/eslint/node_modules/mocha/lib/runner.js:293:7
    at next (/Users/mgol/Documents/projects/public/eslint/node_modules/mocha/lib/runner.js:237:23)
    at Object._onImmediate (/Users/mgol/Documents/projects/public/eslint/node_modules/mocha/lib/runner.js:261:5)
    at processImmediate [as _immediateCallback] (timers.js:336:15)

The line:

    at Context.<anonymous> (/Users/mgol/Documents/projects/public/eslint/tests/lib/formatters/stylish.js:72:26)

points to the place where I invoke:

var result = formatter(code, config);

the line:

    at module.exports (/Users/mgol/Documents/projects/public/eslint/lib/formatters/stylish.js:9:3011)

is the only reference to the reporter file. The line no. 9 is empty in this file and the invocation must be happening way lower in the file but I have no way to get this information from the trace.

Proxyquire messes up with columns

I wanted to mock the chalk module used in ESLint; I might have forgotten about sth and I got an error in mocha:

  3) formatter:stylish when passed one file not found message should return a string without line and column:
     TypeError: Cannot read property 'length' of undefined
      at dotindex (./eslint/node_modules/text-table/index.js:59:31)
      at ./eslint/node_modules/text-table/index.js:11:21
      at Array.forEach (native)
      at forEach (./eslint/node_modules/text-table/index.js:73:31)
      at ./eslint/node_modules/text-table/index.js:10:9
      at Array.reduce (native)
      at reduce (./eslint/node_modules/text-table/index.js:63:30)
      at module.exports (./eslint/node_modules/text-table/index.js:9:20)
      at ./eslint/lib/formatters/stylish.js:9:1767
      at Array.forEach (native)
      at module.exports (./eslint/lib/formatters/stylish.js:9:1244)
      at Context.<anonymous> (./eslint/tests/lib/formatters/stylish.js:197:26)
      at Test.Runnable.run (./eslint/node_modules/mocha/lib/runnable.js:211:32)
      at Runner.runTest (./eslint/node_modules/mocha/lib/runner.js:358:10)
      at ./eslint/node_modules/mocha/lib/runner.js:404:12
      at next (./eslint/node_modules/mocha/lib/runner.js:284:14)
      at ./eslint/node_modules/mocha/lib/runner.js:293:7
      at next (./eslint/node_modules/mocha/lib/runner.js:237:23)
      at Object._onImmediate (./eslint/node_modules/mocha/lib/runner.js:261:5)
      at processImmediate [as _immediateCallback] (timers.js:336:15)

Look at ./eslint/lib/formatters/stylish.js:9:1244 - this file definitely doesn't have such long lines. It's hard to see where an error occurs since there is actually nothing in this line: https://github.com/eslint/eslint/blob/0da23b8f365e0cb1e60e0fc456d8c46735e3a1b2/lib/formatters/stylish.js#L9

Override globals

Would be great if proxyquire could override globals ร  la rewire.

Use case: mocking properties of the process object.

A way to fake require.resolve function

To start I want to say its an excellent module. Thanks for the great work.

Now I do use proxyquire to fake certain modules, that works great. But in my application i use the function require.resolve function to get the path of the dependency but I am not able to fake it.

Example code:

function getPlugin(pluginName){
    var plugin = require(pluginName);
    var pluginPath = require.resolve(pluginName); // ---> Error here

    return {
        api: plugin,
        path: pluginPath
    };
}

Since I use proxyquire so require works but it throws an error on line 3.

Doesn't seem to be overriding require?

I am not sure what is going on but I have been trying multiple mocking/require hijacking libraries to see if I can mock some of my dependencies. I like proxyquire but the problem being proxyquire doesn't seem to be giving me my mocked objects.

// item.js
var parser = require('./parser');

module.exports = {
  someFunctionThatUsesParser: function(){ ... };
}
// item-spec.js
var proxy = require("proxyquire"),
  item;
//jasmine before each
beforeEach(function(){
  var mock = {
    'parser' : {
      myMockedFunction: function(){ ... }
    }
  };
  item = proxy("../src/item", mock);
});
// tests below

Folder structure is:

project/
  |- src/
  |--- item.js
  |--- parser.js
  |- spec/
  |--- item-spec.js

Is that not the way this is supposed to be set up? I have checked to see if the parser object that item uses vs what I have mocked are the same object and they are not. Any Ideas?

Feature Request: Prevent proxyquire from failing if it is being used to mock a .json require

if proxyquire is used to mock a .json file that is loaded in through require, i wonder if it would be better behavior if it was possible for it to not require the real .json file to exist so proxyquire could just operate off the mock solely my main example is config management say for example your writing tests around your configmanager that relies on an env.config file on all your deployment machines, but not necessarily on all the dev boxes, i would like the ability to run the tests for the configmanager without needing the env.json file to exist and instead catch and return the stubbed object defined in proxyquire.resolve without proxyquire trying to resolve the original path provided.

Enhancement

Hey,

I've been giving it a good bit of thought and I think I can squash the global issue without breaking compatibility and without forcing users to use noPreserveCache. I'm sure those methods are still helpful for other edge cases that we haven't thought of, but please consider this solution.

Current

  try {
    return this._parent.require(request);
  } finally {
    if (self._preserveCache) {
      if (cached)
        Module._cache[id] = cached;
      else
        delete Module._cache[id];

      if (ext_super)
        require.extensions[extname] = ext_super;
    }
    else
      delete require.cache[id];
  }

New

  try {
    return this._parent.require(request);
  } finally {
    if (self._preserveCache) {
      // Clear the stubbed cache
      delete require.cache[id];

      // Re-read the module to restore the globals without stubs
      require(request);   

      // Continue restoring the original module as before for state and Singletons
      if (cached)
        Module._cache[id] = cached;
      else
        delete Module._cache[id];

      if (ext_super)
        require.extensions[extname] = ext_super;
    }
    else
      delete require.cache[id];
  }

I'm really leaning towards a PR for this. Of course, at that point, I'm not sure what I'd end up putting in the wiki.

Is it possible to assert that what I proxyquired was actually required?

// foo-test.js
var proxyquire = require('proxyquire');
var foo = proxyquire('../foo', {'../bar: {}});

assert(proxyquire.wasProxied('../bar'));

Can I do something along these lines in order to ensure that my ../bar path hasn't changed since I stubbed the file? This would be helpful for a constantly changing codebase in case the stubbed file moves and then is no longer stubbed.

Relative paths for sub-modules?

Hi, I have an use case where I define some routes directly in a routing.js file, and some other routes are defined by another package. This other package uses path.resolve(modulepath) and then requires that. I've tried a lot of different things, but I wasn't able to figure out what path I should use so that proxyquire is able to mock those.

The use case would be testing that the other package effectively does call app[verb] with the correct endpoint and middleware.

Is there some way I could debug this? Say, does proxyquire have the ability to tell me what modules are required and what paths were used in those require statements, so that I can mock them?

Support for node-webkit?

We have a node-webkit app, that has angularjs services and we 'require' node modules inside them. These files do not have any module.exports. We are writing unit test cases and we want to mock the require's present in these files. Any plan to support this case in future?

Thanks

Add documentation: Only works on functions

I've run into situations where I want to modify the global config object (which is basically just json). Proxyquire seems like an excellent tool for this, but after much trial and error I've come to the (correct?) conclusion that this module is only designed to work on replacing functions that are dependencies of a module, not values. It might be helpful to document proxyquire doesn't change values for other wayward developers like myself (or maybe I'm alone in wanting to do this).

For posterity's sake, in node v0.10.x, you can modify values thusly:

require('your-module').value = 'STUB VALUE';

It looks odd, but it seems to work for me.

failure of fakeStub for certain require modules when used in combination with blanketJS

proxyquire has an issue when combined with blanketJS

    var foo = proxyquire('foo', { 'path': pathStub }); //is ok
    var bar = proxyquire('./bar', { 'path': pathStub }); //not okay

the bar gets fully parsed into absolute path say "c:\node\website\xyz\lib\bar.js".

Cause:
I observed that this is happening as a result of require.extensions[extname] also being present in the blanketJS code base as require.extensions['js'].

the blanketJS is being loaded after the proxyquire and thus overrides the method signature.

Environment:

  • node 10 on Windows
  • mocha for testing
  • powered by grunt

Does not work with strict mode modules

Due to use of caller, any modules that have "use strict" at the top and call the proxied require will immediately break.

It looks like you need the caller's __dirname in order to resolve relative modules. I think there are a variety of ways to do this, perhaps involving require.resolve, require.cache, module.parent, or some combination thereof.

You mentioned on Twitter stripping the strict mode for proxyquire "because it is only used for testing." That's not correct; strict mode has runtime semantic changes that are important to preserve (e.g. better exceptions, different eval behavior, no implicit global this).

Cannot use with transpiled modules

Following #64, I still cannot use babel-node test.js, proxyquire will have no effect:

module.js

var dep = require('dep');
console.log(dep);

test.js

var proxyquire = require('proxyquire');
var mod = proxyquire('./module', {dep: function(){console.log('weee')}});

In a terminal:

babel-node test.js
# output contains the original dep

What can I do?

Proxyquire will not stub falsey value

requireStubs = {
            './models/recacheModel': modelMock,
            './server': serverStub,
            'config': {
                'recache': {
                    'auto': true,
                    'interval': 50
                },
                'nodeTime': false //does not work with null either
            }
        };         
        var fileUnderTest = proxyquire(loadPath + 'startServer.js', requireStubs);
var nodeTimeConfig = require('config').nodeTime;
if(nodeTimeConfig){
    require('nodetime') //blows up
}

In this particular case I worked around this by changing my config setup, but being able to stub something falsey would be a nice feature.

This would probably require some kind of hack/convention other than just property: false because of the way objects work

Cant proxy when path is variable

I'm using a variable (__BASE) for the root directory but seems like its not working.

Is there an easy fix for that?

that's working great:

proxiedLocation = proxyquire(`${__BASE}/app/adapters/location`,{
    '../services/location': locationService
 });

but when I'm changing the '../services/location' to __BASE + /app/services/location or SERVICE_LOCATON_PATH or the es6 syntax its not working.

Thanks.

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.