How To Test A Recursively Called Function In Nodejs?
Solution 1:
I've written an example of how you could test your recursively called function here:
https://jsfiddle.net/Fresh/qppprz20/
This test makes use of the Sinon javascript test library. You can set-up the behaviour of the stub on the nth call, hence you can simulate when no user is returned and then subsequently when a user is returned e.g.
// Stub the method behaviour using Sinon javascript frameworkvar user = new User();
var userStub = sinon.stub(user, 'findOneAsync');
userStub.onFirstCall().returns(null);
userStub.onSecondCall().returns({});
Hence onFirstCall simulates the first call and onSecondCall the recursive call.
Note that in the full example I've simplified checkIfUserExists, but the same test premise will apply for your full method. Also note that you would additionally have to stub your delay method.
Solution 2:
There are several libraries that can be used for testing time-related events. As far as I know the most common solution is Lolex - https://github.com/sinonjs/lolex, earlier part of Sinon project. The problem with Lolex is that it forwards the timers synchronously, thus ignoring events such as native node promises or process.nextTick
(although it does fake setImmediate
properly) - therefore you can get into some nasty issues. Be careful about external libraries - for example, bluebird
caches the initial setImmediate
, so you need to handle it somehow manually.
A different choice is Zurvan - https://github.com/Lewerow/zurvan (disclaimer: I wrote it). It's a bit harder to tackle than Lolex, since it uses promises heavily, but behaves properly in presence of microqueued tasks (process.nextTick
, native Promise
) and has a built-in compatibility option for bluebird.
Both libraries allow you to expire time-related events on arbirary length and override also Date
instances (zurvan overrides process.uptime
and process.hrtime
as well). Neither of them is safe to use if you perform actual async IO in tests.
Solution 3:
I'm not sure why you wanted to use a recursive solution instead of an iterative solution - but it might be easier to write it iteratively if for no other reason than so you don't blow the stack:
do{
let user = await User.findOneAsync({});
// if there is no user delay one minute and check againif(user === null){
await delay(1000 * 60 * 1);
}
else{
returntrue;
}
}while (!user);
Haven't tested or run this through an interpreter - but you get the idea.
Then in your testing mode - just provide a test user. Since you'll probably need to write tests that use a reference to the user anyway.
Post a Comment for "How To Test A Recursively Called Function In Nodejs?"