Redis mocha 测试用例问题

Redis mocha Test case issue

我有一个文件调用cache.js

var redisCache = redis.createClient(port, name);
redisCache.on("error", function(err) {
  logger.error("Error connecting to redis", err);
});

exports.setExp = function(key, timeLeft, data){
    redisCache.set(key, JSON.stringify(data), function (err, reply) {
      console.log("error "+err);
      console.log("reply "+reply);
      if(err) {
        console.log("error "+err.command + err.code);
        logger.info("This errror on set key related to node_redis");
      }
      if(reply == 'OK') {
        redisCache.expire(key, timeLeft, function (err, reply) {
          if(err) {
            logger.info("This errror on expire key related to node_redis");
          }
          if(reply === 1) {
            logger.info(key+" key expire time set as "+timeLeft+" successfully!");
          }
        });
      }
    });
  }

现在我想为上面的 setExp 函数编写测试用例,但是 node_redis 如何让我远离 return 错误为 null 并回复为 OK

下面是我的测试用例。

var cache = require(path.join(__dirname,'..','/cache'));
describe('cache', function () {
  it('Cache #setExp() ', function (done) {
      var result = cache.setExp(undefined, 0, []);
        assert.equal('OK', results);
        done()
  })
})

如果我更改它应该遵循我根据 node_redis test case

提到的以下错误
var result = cache.setExp('foo', 10, []);

它应该 return 我的错误称为 ERR wrong number of arguments for 'set' command

var result = cache.setExp(undefined, 0, []);

它应该接受以下错误日志作为 assert.equal(err.command, 'SET');

请建议我实现此目标的正确方法。

你的想法在这里似乎几乎完全错误。

首先,您编写和使用 setExp 就好像它是同步操作一样,但事实并非如此。它会 return 在向redis发出请求之前。它也从来没有 returns 任何东西,所以即使它是同步的,result 在你的测试中也永远是 undefined.

您需要将 setExp 重新设计为异步操作,方法是使用 async 关键字、return 承诺或让它接受回调函数。

其次,如果你想为一个Redis键设置一个过期时间,你应该在你设置键本身的时候设置它,而不是设置一个没有过期的键,然后再尝试添加过期时间。否则你 运行 过期设置失败的风险,然后以永不过期的孤立密钥结束。

这是一个例子,使用节点的 util.promisify to as described in the node_redis docs:

var redis = require('redis');
var {promisify} = require('util');
var redisCache = redis.createClient(port, name);
redisCache.on("error", function(err) {
  logger.error("Error connecting to redis", err);
});
var set = promisify(redisCache.set).bind(redisCache);

exports.setExp = function(key, timeLeft, data){
    return set(key, JSON.stringify(data), 'EX', timeLeft.toString(10))
        .then((reply) => {
            if (reply !== 'OK') throw new Error(reply);
            return reply;
        });
};

在你的测试中你会做这样的事情:

var cache = require('../cache');

describe('cache', function () {
    it('Cache #setExp() ', function () {
      let key = 'some key';
      let timeLeft = 12345;
      let data = { foo: 'bar' };

      return cache.setExp(key, timeLeft, data)
        .then((result) => {
            assert.equal('OK', result);
        });
    });
});

此外,resultsresult 不是一回事。在您的测试用例中,没有名为 results.

的变量

哦,不要这样做:

var cache = require(path.join(__dirname,'..','/cache'));

require 已经支持相对于 __dirname 的路径。只需这样做:

var cache = require('../cache');