javascript - 用 Sinon 模拟 Redis 构造函数

标签 javascript testing redis mocha.js sinon

我想找出一种在这个模块中模拟 redis 的方法:

const Redis  = require('ioredis');
  const myFunction = {
    exists: (thingToCheck) {
      let redis_client = new Redis(
        6379,
        process.env.REDIS_URL,
        {
          connectTimeout: 75,
          dropBufferSupport: true,
          retryStrategy: functionHere
        });

    redis_client.exists(thingToCheck, function (err, resp) {
     // handlings in here
    });
  }
};

使用这个测试代码:

const LambdaTester = require('lambda-tester');
const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
const mockRedis = sinon.mock(require('ioredis'));

describe( 'A Redis Connection error', function() {
    before(() => {
        mockRedis.expects('constructor').returns({
            exists: (sha, callback) => {
                callback('error!', null);
            }
        });
      });

      it( 'It returns a database error', function() {
          return LambdaTester(lambdaToTest)
              .event(thingToCheck)
              .expectError((err) => {
                   expect(err.message).to.equal('Database error');
              });
      });
});

我也尝试了一些变体,但我有点卡住了,因为我基本上需要模拟构造函数,但我不确定 Sinon 是否支持这个?

mockRedis.expects('exists').returns(
  (thing, callback) => {
    callback('error!', null);
  }
);
sinon.stub(mockRedis, 'constructor').callsFake(() => console.log('test!'));
sinon.stub(mockRedis, 'exists').callsFake(() => console.log('test!'));

不确定在这里还能尝试什么,我也尝试使用 rewire按照建议here ,但使用 mockRedis.__set__("exists", myMock); 从不设置该私有(private)变量。

我最终想伪造我的错误路径。
我很想听听其他人在做什么来测试节点 js 中的 redis 😄。

最佳答案

您的问题不在于 Sinon 是否支持这个或那个,而是缺少对“类”在 Ecmascript 中的工作方式的理解,如在测试代码中试图 stub constructor 属性所示。这永远行不通,因为该属性与任何结果对象的结果无关。它只是对用于创建对象的函数的引用。我已经涵盖了a very similar topic on the Sinon tracker您可能有兴趣阅读以获得一些核心 JS foo :-) 基本上,不可能对构造函数进行 stub ,但您可以通过 DI 或链接接缝强制您的代码在其位置使用另一个构造函数。

事实上,在同一个线程中有几个答案,您会看到我介绍了一个示例,说明我自己如何设计一个 Redis 使用类,以便通过支持依赖注入(inject)轻松测试。你可能想要 to check it out ,因为它或多或少直接适用于您上面的示例模块。

您已经尝试过的另一种技术是使用链接接缝(使用rewire)。 Sinon 主页有一个 nice article这样做。 rewireproxyquire 都可以很好地完成这里的工作:我认为您只是通过用 mock 包装 require 语句使事情复杂化了一点。

尽管我是 Sinon 维护者团队的一员,但我从未使用过 mock 功能,所以我不能告诉你如何使用它,因为我认为它掩盖了测试,但为了获得基本的使用 rewire 链接接缝工作 我基本上会先删除所有 Sinon 代码,然后开始基本案例(删除 redis 用于您创建的 stub 模块)。

然后,根据需要添加 Sinon 代码。

关于javascript - 用 Sinon 模拟 Redis 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44294170/

相关文章:

redis - 最适合 redis 中的数据结构以维护用户配置文件的值(value)

javascript - 如何在 React js 上使用历史记录重定向到另一个页面?

javascript - knockout 验证 - 验证未绑定(bind)到正确的对象实例

mysql - 带有 Typescript 和 Mysql 的 Node.js 测试路由模拟服务

testing - 测试框架/快速检查/cabal : Passing options to testfunction with 'cabal test'

java - 使用 Vertx 时用于 Redis 的 ORM 框架

asp.net-web-api - ASP.Net Web API - 扩展大量写操作

javascript - 将一个 HTML 元素 (div) 放置在另一个 HTML 元素 (li) 上

javascript - 查找并删除字符串中的特定单词

node.js - 在 mongodb 中设置假数据进行测试