2016-06-02 2 views
0

Ich habe eine Funktion, die am Ende eine andere Funktion zurückgibt, die basierend auf dem, was in der ersten Funktion ausgeführt wurde, aufgerufen wird.Testen, dass eine Funktion in einer Funktion zurückgegeben wird

function createOption(endPoint, options, body, post) { 
    if(!options) { 
    options = { 
     hostname: 'testurl.com', 
     path: '/rest/api/content/' + endPoint, 
     port: 443, 
     headers: { 
     'Accept': 'application/json', 
     'Content-Type': 'application/json', 
     'Authorization': getAuthorization() 
     } 
    } 
    if(body) { 
    if(post) options.method = 'POST'; 
    else options.method = 'PUT'; 
    } 
    else options.method = 'GET'; 

    return apiCall(options, body) 
} 

function apiCall(options, body) { 
    var deferred = Q.defer(); 

    var request = https.request(options, function (res) { 
     var resBody = ''; 
     res.on('data', function appendData(responseChunk) { 
      resBody += responseChunk; 
     }); 
     res.on('end', function useBody() { 
      try { 
       var parsed = JSON.parse(resBody); 
       if(parsed.statusCode) 
        deferred.reject(new Error('Request failed')); 
       else 
        deferred.resolve(parsed); 
      } 
      catch(error){ 
       deferred.reject(new Error(resBody)); 
      } 
     }); 
    }); 
    if(body) 
     request.write(body); 
    request.end(); 
    request.on('error', function (errorData) { 
     deferred.reject(new Error('Error making call - :\n' + errorData)); 
    }); 

    return deferred.promise; 
} 

module.exports = { 
    createOption: createOption, 
    apiCall: apiCall 
} 

Um dies zu testen, ich versuche, dass apiCall zu behaupten, wird unter Verwendung von Sinon Spionen genannt, aber es wird nicht erkennen.

var api = require('../src/api'); 
var chai = require('chai'); 
var sinon = require('sinon'); 

var expect = chai.expect; 

describe('api test procedure', function() { 
    it('should create e based on inputs a, b, c, d and call e', function() { 
    var spy = sinon.spy(api, 'apiCall'); 

    api.createOption('', null, null, null); 

    expect(spy.called).to.be.true; 
    }); 
}); 

Was mache ich hier falsch? Wenn ich eine Funktion ausspioniere, die nicht am Ende aufgerufen wird, erkennt sie, dass sie aufgerufen wird, aber nicht am Ende.

edit: aktualisierte Code

+2

Es wäre hilfreich, wenn Sie den * real * Code schreiben würden, oder zumindest ein Extrakt. In dem von Ihnen geposteten Code wird "foo" als eine Funktion deklariert, und es gibt keinen Hinweis darauf, wie es mit einem "api" -Objekt zusammenhängt. Außerdem wird 'bar()' ohne Objektverweis aufgerufen. – Pointy

Antwort

1

Extrem vereinfachte, Ihr Code wie folgt aussieht:

var sinon = require('sinon'); 

function A() { 
    B(); 
} 

function B() { 
    console.log('hello world'); 
} 

var obj = { 
    A : A, 
    B : B 
}; 

// Spy on B 
var spy = sinon.spy(obj, 'B'); 

// Call A 
A(); 

// This should be true! 
console.log(spy.called); 

jedoch protokolliert false es.

Der Grund dafür ist, dass Sinon auf obj.B spioniert, was bedeutet, dass es obj.B mit einer anderen Funktion (der Spion) ersetzt, die die ursprünglichen obj.B anrufen und aufzeichnen, wie es genannt wurde (was args, etc).

Jedoch ruft Aobj.B überhaupt nicht auf, es ruft B. Sicher, obj.B ist eine Referenz auf diese Funktion, aber das ist egal: Sinon kann obj.B nur durch einen Spion ersetzen, aber nicht das Original B.

Um dies zu lösen, sollte A auch obj.B anrufen.

Oder in Ihrem Fall:

return exports.apiCall(options, body);