首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用sinon模拟ioredis连接

无法使用sinon模拟ioredis连接
EN

Stack Overflow用户
提问于 2021-05-16 11:45:29
回答 1查看 954关注 0票数 0

我正在尝试为下面的服务创建一个单元测试,使用Sinon。如您所见,在构造函数上调用"_createRedisConnection“,因此在单元测试中,我必须模拟Redis连接。

代码语言:javascript
复制
import { inject, injectable } from "inversify";
import { TYPES } from "../../inversify/types";
import { Logger } from "winston";
import { Config } from "../../interfaces/config.interface";
import { BaseService } from "../base.service";
import * as Redis from "ioredis";
import { HttpResponseError } from "../../interfaces/HttpResponseError.interface";
import { BaseResponse } from "../../interfaces/BaseResponse.interface";

@injectable()
export class RedisService extends BaseService {
  private _redisClient;
  private _isRedisConnected: boolean;

  constructor(@inject(TYPES.Logger) private logger: Logger,
    @inject(TYPES.Config) private config: Config) {
    super(logger, config);
    this._isRedisConnected = false;
    this._createRedisConnection();
  }

  public async set(key, value, epu, receivedTtl): Promise<BaseResponse> {
    if (this._isRedisConnected) {
      const encryptedKey = this.createEncryptedKey(epu, key);

      if (!encryptedKey || !value) {
        throw new HttpResponseError("General error", "Missing attributes in request body", 422);
      }

      const ttl = this.limitTtl(receivedTtl);

      let response;

      if (ttl >= 0) {
        await this._redisClient.setex(encryptedKey, ttl, value)
        .then(() => {
          response = new BaseResponse("success", "Data saved successfully", ttl);
        })
        .catch((errorMessage: string) => {
          throw new HttpResponseError("General error", `Error while saving data. err = ${errorMessage}`, 500);
        });
      } else {
        await this._redisClient.set(encryptedKey, value)
        .then(() => {
          response = new BaseResponse("success", "Data saved successfully", ttl);
        })
        .catch((errorMessage: string) => {
          throw new HttpResponseError("General error", `Error while saving data. err = ${errorMessage}`, 500);
        });
      }

      return response;
    }

    throw new HttpResponseError("General error", "Cache is not responding", 503);
  }

  private _createRedisConnection(): void {
    this._redisClient = new Redis({
      sentinels: [{ host: this.config.redisConfig.host, port: this.config.redisConfig.port }],
      name: "mymaster",
      dropBufferSupport: true,
    });

    this._redisClient.on("connect", () => {
       this._isRedisConnected = true;
      });

    this._redisClient.on("error", (errorMessage: string) => {
      this._isRedisConnected = false;
    });
  }
}

我的问题是嘲笑红宝石的联系。我正在尝试对“connect”事件进行存根,但是在调试它时,我发现事件从未触发过(甚至不是错误事件)。

代码语言:javascript
复制
import "reflect-metadata";
import { expect } from "chai";
import { Logger } from "winston";
import * as Redis from "ioredis";
import { stub } from "sinon";
import { RedisService } from "./redis.service";
import { config } from "../../config";

class LoggerMock {
    public info(str: string) { }
    public error(str: string) { }
}

describe("RedisService Service", () => {
    const redisStub = stub(Redis.prototype, "connect").returns(Promise.resolve());
    const logger = new LoggerMock() as Logger;
    const redisService = new RedisService(logger, config);

    it("Should success set data", async () => {
        const redisClientStub = stub(Redis.prototype, "set").resolves(new Promise((resolve, reject) => { resolve('OK'); }));
        const result = await redisService.set("key", "value", "epu", -1);
        expect(result.message).to.equals("success");
        expect(result.response).to.equals("Data saved successfully");

        redisClientStub.restore();
        redisStub.restore();
    });
});

测试此服务的正确方法是什么?为什么在这样的情况下不会触发任何事件?

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-18 19:29:35

这是一个如何对ioredis Redis.prototype.connect进行存根的示例。

代码语言:javascript
复制
// File test.js
const { expect } = require('chai');
const Redis = require('ioredis');
const sinon = require('sinon');

describe('connection', function () {
  it('should emit "connect" when connected', function (done) {
    // Create stub on connect.
    const stubRedisConnect = sinon.stub(Redis.prototype, 'connect');
    stubRedisConnect.callsFake(async function () {
      // This will trigger connect event.
      this.setStatus('connect');
    });
    const redis = new Redis();
    redis.on('connect', function () {
      // Do not forget to restore the stub.
      stubRedisConnect.restore();
      done();
    });
  });
});

当我在我的终端上运行时:

代码语言:javascript
复制
$ npx mocha test.js


  connection
    ✓ should emit "connect" when connected


  1 passing (6ms)

如果测试存根失败,将出现2000 If的默认超时错误,因为未被调用。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67556276

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档