Closed souly1 closed 8 years ago
We need at least some code to be of any help
Sure:
var ipinfo = require("ipinfo");
exports.bar = function(){
ipinfo(ip, function (err, cLoc) {
//cLoc holds the location data
}
};
The spec class:
ipInfoMock = function(ip, callback){
callback();
};
ipInfoMock['@global'] = true;
proxyquire("../../../node_modules/ipinfo/lib/index", ipInfoMock );
...
...
foo.bar();
assert.equal(ipInfoMock.prototype.constructor.called, true);
Fails
Right. Your problem is that you're not passing any of the right values to proxyquire. Proxyquire expects 1) string paths that point to your source code 2) objects where the keys are module ids/paths relative to your source and the values are the full/partial replacement. You need to pass './mysrc.js', {ipinfo: ipInfoMock}
.
If it's easier to understand, you're expecting proxyquire to magically globally override modules that have already been loaded. That's nearly impossible to actually do. What's really happening is that proxyquire can override the module loader when loading your code and ensure that you get an opportunity to manipulate the top level and even the global dependency tree just for that call.
Oops, really sorry, I've just pasted a wrong version of my attempt, here's and updated version of the proxyquire call:
proxyquire("../../../modules/foo", {'ipinfo': ipInfoMock} );
This is what fails for me and I'm unclear as to why
Adding here code from ipInfo's index.js, pretty short:
var IpInfo = module.exports = function (type, callback) {
var url = null;
if (typeof type === "function") {
url = IpInfo.HOSTNAME + "json";
callback = type;
} else if (IpInfo.IP_REGEX.test(type)) {
url = IpInfo.HOSTNAME + type + "/json";
} else {
url = IpInfo.HOSTNAME + type;
}
JsonRequest(url, callback);
};
IpInfo.HOSTNAME = "http://ipinfo.io/";
IpInfo.IP_REGEX = /^\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b$/;
That should work ok, but why aren't you assigning the proxyquire
value to anything? Can I get something I can run?
Sure, https://ide.c9.io/souly1/ipinfo_issue
Click run on displaying geoSpec.js, all should be ready (mocha will run).
Thanks!
That's not how proxyquire works. You need to assign the return value of proxyquire
, not expect the ability to manipulate requires that already happened.
humph, I'm pretty sure it worked for me in other modules... seeing what i meant, do you think there is a way to run the same result i want from the test?
I don't know what result you're expecting. As long as you assign the proxied module instead of assuming some global manipulation will happen (it won't) you should be okay.
OK, Finally understood what you were saying, fixed the c9 example. If fixing the example written above basically all that was required was:
foo = proxyquire("../../../modules/foo", {'ipinfo': ipInfoMock} );
thanks again for the patience @bendrucker Cheers
Hi, recently I've added the http://ipinfo.io node js wrapper (https://github.com/IonicaBizau/node-ipinfo) to my app and no matter what i've tried, I'm not able to get proxyquire+sinon to mock its behaviour. I assume its due to it exporting a function instead of an object, I've tired global=true flag written here, but no success. Any recommendations on how to approach this? Thanks