Wednesday, August 15, 2012

My Little Spy Function

I needed to spy on functions of an object and quickly came up with this little code to do much as i wanted.. For more advanced spying on javascript functions in your tests, consider using sinon.js or some other framework.
function Spy(funcName,obj){

 var originalFunction ;
    if(typeof obj === 'object'){
        originalFunction = obj[funcName];
    }
    else{
        originalFunction = global[funcName]
    }

 var numCalled = 0;
 var invocations = [];
 var spy = function(){
  numCalled++;
  invocations.push(arguments);
        if(typeof obj === 'object')
  return originalFunction.apply(obj,arguments);
        else
            return originalFunction.apply(global,arguments);
 }
 spy.calledOnce = function(){
  return numCalled == 1 ? true : false;
 }
 spy.times = function(num){
  return num == numCalled ? true : false ;
 }
 spy.firstCallWith = function(){
  return invocations[0];
 }
 spy.nthCallWith = function(n){
  return invocations[n-1];
 }
    if(typeof obj === 'object'){
        obj[funcName] =  spy;
    } else {
        global[funcName] =  spy;
    }
 return spy;
}
Now to spy on function emit of Dummy socket module below
var Socket = function(){
    function emit(name,message){
    }
    return {
        "emit" : emit
    }
}
exports['Line Parser not invoked since no socket is connected'] = function(test){
    test.expect(1);
    //given
    var socket = new Socket();
    var spy = new Spy("emit" , socket);
    //Run the test
    //verify the spy
    test.ok(spy.calledOnce(), "Socket.emit has been called once");

    test.done();
}