【问题标题】:Mocking Redis Constructor with Sinon用 Sinon 模拟 Redis 构造函数
【发布时间】:2017-11-01 19:31:15
【问题描述】:

我正在想办法在这个模块中模拟 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');
              });
      });
});

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

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); 从未设置该私有变量。

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

【问题讨论】:

  • 也许你可以看看ioredis的单元测试,github.com/luin/ioredis/blob/master/test/helpers/mock_server.js,ioredis是如何搭建一个假服务器的。
  • 很酷,谢谢!我最终只是用 Docker 创建了一个本地 redis 服务器并将其杀死以进行错误测试,但是当我有更多时间时,我想构建一个更好的模拟。
  • 但是上面的方法确实很好用,只是不想有一个 docker 依赖来运行测试
  • 是的,Docker 非常适合构建测试数据库。就我而言,我通常将应用程序连接到 docker 中的 redis 集群,但我会存根所有 redis 操作。所以redis总是空的,但是省了很多力气。

标签: javascript testing redis mocha.js sinon


【解决方案1】:

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

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

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

虽然我是 Sinon 维护者团队的一员,但我从不使用 mock 功能,所以我无法告诉您如何使用它,因为我认为它会掩盖测试,但要使用 @ 让基本链接接缝正常工作987654329@ 我基本上会先删除所有 Sinon 代码,然后开始进行基本案例(删除您创建的存根模块的 redis)。

只有这样,根据需要添加诗农代码。

【讨论】:

  • 这非常有用,谢谢!今天学到了一些新东西:D
  • 甜蜜,如果有人能帮忙,总是很好。如果您应该继续执行此操作并被卡住,请回复。如果需要,可能会更新一些细节。
猜你喜欢
  • 2013-01-12
  • 2020-07-11
  • 1970-01-01
  • 1970-01-01
  • 2020-08-26
  • 1970-01-01
  • 2019-11-24
  • 2017-07-23
  • 2021-04-14
相关资源
最近更新 更多