Javascript 摩卡咖啡;Sinon-监视从节点异步回调中调用的函数?
问题摘要:我想测试在NodeJS异步回调(见下面的代码)内部调用的Javascript 摩卡咖啡;Sinon-监视从节点异步回调中调用的函数?,javascript,node.js,mocha.js,sinon,chai,Javascript,Node.js,Mocha.js,Sinon,Chai,问题摘要:我想测试在NodeJS异步回调(见下面的代码)内部调用的redisCallback(),是否使用预期参数调用了预期次数 背景信息(如果是TL;DR则跳过): 我四处寻找,但只找到了昆特的解决方案。我不确定在这种困境下,摩卡+西农的等价物是什么 在我当前的测试中,Chai断言响应为AssertionError:expected false等于true 但是,我通过调用this.redisCallback在updateRedis函数(正在测试)内部,但在redisClient.getasy
redisCallback()
,是否使用预期参数调用了预期次数
背景信息(如果是TL;DR则跳过):
我四处寻找,但只找到了昆特的解决方案。我不确定在这种困境下,摩卡+西农的等价物是什么
在我当前的测试中,Chai断言响应为AssertionError:expected false等于true
但是,我通过调用this.redisCallback
在updateRedis
函数(正在测试)内部,但在redisClient.get
async回调外部进行了测试,在这种情况下,测试套件正确地检测到回调已被触发,我的测试成功
这告诉我这是一个异步问题。如何让Mocha/Chai等到redisClient.get
回调完成后再检查断言
代码
编写这段代码是为了解决Node的一个问题,在Node中,我需要检查Redis中的一个键是否与系统命令返回的值不同,如果它已更改,请在Redis中设置新值。由于系统命令值将在异步调用的包含范围内(因此,不可访问/不可靠),因此我创建了一个函数,该函数返回redisClient.get回调所需的回调,但将使用的键和系统命令值传递到闭包中,以记忆回调的值
与我使用HighlandJS编写的内容非常接近:
var redisClient = require('redis').createClient(config.redis.port, config.redis.host),
_ = require('highland');
// ...
redisCallback = function (resultsHash, redisKey, redisGetValue) {
var systemCmdValue = resultsHash[redisKey];
if (redisGetValue != systemCmdValue) {
redisClient.set(redisKey, systemCmdValue, function (err) { // handle errors });
}
};
// ...
updateRedis = function (err, stdout, stderr) {
// Do some stuff that's not important to this problem
var resultsHash = parseCmdResults(stdout),
redisKeys = Object.keys(resultsHash),
curriedRedisCallback = _.curry(this.redisCallback, resultsHash);
get = _.wrapCallback(redisClient.get.bind(redisClient));
redisKeys.each(function (key) {
get(key).each(curriedRedisCallback(key));
});
};
vanilla NodeJS和JavaScript中的等效实现:
var redisClient = require('redis').createClient(config.redis.port, config.redis.host);
// ...
redisCallback = function (resultsHash, redisKey, redisGetValue) {
var systemCmdValue = resultsHash[redisKey];
if (redisGetValue != systemCmdValue) {
redisClient.set(redisKey, systemCmdValue, function (err) { // handle errors });
}
};
redisCallbackWrapper = function (resultsHash) {
return function (redisKey) {
return function (redisGetValue) {
this.redisCallback(resultsHash, redisKey, redisGetValue);
};
};
};
// ...
updateRedis = function (err, stdout, stderr) {
// Do some stuff that's not important to this problem
var resultsHash = parseCmdResults(stdout),
redisKeys = Object.keys(resultsHash),
callback = redisCallbackWrapper(resultsHash),
key;
for (var i = 0; i < redisKeys; i++) {
key = redisKeys[i];
redisClient.get(key, callback(key));
}
};
意识到要得到我想要的,我必须stub
redisClient.get
,如果我想测试redisCallback函数的参数,就要为每次调用注入我期望的值。这就带来了一个问题,我还没有能够成功地存根任何redisClient方法。现在,我已经知道了如何存根node_redis函数,但问题仍然是,如果不存根使用回调的异步函数,我无法正确监视在节点异步回调中执行的任何函数。理想情况下,我的测试不必知道在异步回调中调用要验证的函数的实现细节。最好的测试方法是什么?如果我想测试在上述代码中调用了回调
,是否有办法避免中断redisClient.get
方法??
describe('when valid arguments are provided to updateRedis', function () {
var err, stdout, stderr, parsedStdout, key0, key1;
before(function () {
err = undefined;
stderr = undefined;
stdout = 'key0/value0\nkey1/value1';
key0 = 'key0';
key1 = 'key1';
parsedStdout = {};
parsedStdout[key0] = "value0";
parsedStdout[key1] = "value1";
sinon.spy(myModule, 'redisCallback');
});
after(function () {
myModule.redisCallback.restore();
});
it('calls redisCallback with the expected arguments the expected number of times', function (done) {
myModule.updateRedis(err, stdout, stderr);
// If I can get to the point where it's detected that redisCallback has been called at all,
// I can follow the documentation to figure out how to test that it's called with the expected args the expected number of times.
expect(myModule.redisCallback.called).to.equal(true);
done();
});
});