测试正在返回函数中的函数
Testing that a function in a function is being returned
我有一个函数,它在最后 returns 根据第一个函数中完成的操作调用另一个函数。
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
}
为了测试这一点,我试图断言 apiCall 是使用 sinon 间谍调用的,但它不会检测到这一点。
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;
});
});
我在这里做错了什么?当我监视一个没有在最后调用的函数时,它会检测到它正在被调用,但不是在最后。
编辑:更新代码
极度简化,您的代码如下所示:
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 );
但是,它记录 false
。
原因是 Sinon 正在监视 obj.B
,这意味着它将 obj.B
替换为另一个将调用原始 obj.B
的函数(间谍)并记录它是如何进行的被调用(哪个参数等)。
然而,A
根本没有调用 obj.B
,它调用了 B
。当然,obj.B
是对那个函数的引用,但这并不重要:Sinon 只能用间谍替换 obj.B
,但不能替换原来的 B
。
要解决这个问题,A
也应该调用 obj.B
。
或者,在您的情况下:
return exports.apiCall(options, body);
我有一个函数,它在最后 returns 根据第一个函数中完成的操作调用另一个函数。
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
}
为了测试这一点,我试图断言 apiCall 是使用 sinon 间谍调用的,但它不会检测到这一点。
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;
});
});
我在这里做错了什么?当我监视一个没有在最后调用的函数时,它会检测到它正在被调用,但不是在最后。
编辑:更新代码
极度简化,您的代码如下所示:
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 );
但是,它记录 false
。
原因是 Sinon 正在监视 obj.B
,这意味着它将 obj.B
替换为另一个将调用原始 obj.B
的函数(间谍)并记录它是如何进行的被调用(哪个参数等)。
然而,A
根本没有调用 obj.B
,它调用了 B
。当然,obj.B
是对那个函数的引用,但这并不重要:Sinon 只能用间谍替换 obj.B
,但不能替换原来的 B
。
要解决这个问题,A
也应该调用 obj.B
。
或者,在您的情况下:
return exports.apiCall(options, body);