Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 摩卡咖啡;Sinon-监视从节点异步回调中调用的函数?_Javascript_Node.js_Mocha.js_Sinon_Chai - Fatal编程技术网

Javascript 摩卡咖啡;Sinon-监视从节点异步回调中调用的函数?

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

问题摘要:我想测试在NodeJS异步回调(见下面的代码)内部调用的
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();
  });
});