在打字稿测试中模拟第三方库(ioredis)

Mocking third party library (ioredis) in typescript tests

我很难在我的打字稿测试中模拟第三方库。

我正在基于这个 typescript-starter 库制作一个库。它使用 ava 进行测试。

在我的例子中,我试图模拟 ioredis 的主要 class,这样我的测试就不会尝试建立真实的数据库连接。

我试过使用sinon, testdouble.js, and mockery.

我在 sinon 中尝试了以下方法

let redisStub = sinon.stub(IORedis)
sinon.assert.called(redisStub.Cluster)

使用 testdouble 我尝试了很多东西,包括;

td.replace('ioredis') // #1
td.replace('./homeMadeIoredisWrapperClass') // #2

我试过了mockery

mockery.enable()
mockery.registerMock('ioredis', {some: 'object'})

我也尝试了许多其他变体,比如总是在方法中使用 require('ioredis')

我是不是想做一些不可能的事情?我虽然 stubbing/mocking 数据库是一件很正常的事情,但我似乎无法弄清楚。

也许我的设计有缺陷,我可能试图模拟错误的东西?一些帮助将不胜感激!


Ps。在重要的情况下,我正在尝试创建一个非常简单的 ioredis 连接包装器。

我对我的代码有一些误解/问题导致了这个问题。也许这可以启发遇到此问题的其他人;

  1. 我在 td.replace 之前要求 "everything" (import { MyLibrary } from "myLibrary"),这使得替换语句发生在代码需要模块之后。原因是示例测试是在 typescript-starter repo. I have now made a PR to fix the underlying problem.
  2. 中以特定方式设计的
  3. 我正在 运行 并行进行 ava 测试,这导致 td.reset() 在我的一些回调被触发之前发生,在许多情况下有效地阻止了 replace 工作. ava中的解决方法,用test.serial(...代替test(...。是的,测试会 运行 变慢,但它们会起作用。您可以为每个测试创建一个单独的文件,以在 ava.
  4. 中获得真正的并行 运行s

testdouble GitHub 页面中也有一些有用的 wiki 条目; https://github.com/testdouble/contributing-tests/wiki/Don%27t-mock-what-you-don%27t-own https://github.com/testdouble/contributing-tests/wiki/SAFE-test

希望有人觉得这有用。

您可以仅使用 sinon 模拟 ioredis(版本 4.16.2)。您必须模拟连接方法。

import ioredis from "ioredis";

sinon.stub(ioredis.prototype, "connect").returns(Promise.resolve());
sinon.stub(ioredis.prototype, "get").returns(Promise.resolve({ data: "hello" }));