Jest:如何使用构造函数手动模拟模块(ioredis)

jos*_*316 1 jestjs

我正在遵循 Jest 文档中的手动模拟示例 here

我正在尝试将此示例扩展到我自己的项目和我对 ioredis 的手动模拟( mocks /ioredis.js)。我正在尝试用我自己的(这样我可以返回测试值)来模拟 ioredis 客户端 hget,但是由于我需要使用构造函数创建一个 redis 客户端(让客户端 = Redis.new),我遇到了麻烦在我可以访问模拟的 client.hget 之前。

这是我对 ioredis 的手动模拟:

// __mocks__/ioredis.js
/* eslint-env node */
'use strict';

const IORedis = jest.genMockFromModule('ioredis');

const hget = jest.fn()
  .mockImplementationOnce(cb => cb(null, '123'))
  .mockImplementationOnce(cb => cb(null, '456'));

// this approach does not work, I'm wondering if I have to create the client
IORedis.hget = hget;  
module.exports = IORedis;
Run Code Online (Sandbox Code Playgroud)

当我测试时,我可以看到 ioredis 确实被嘲笑了,如果我在使用前在实际模块中执行 console.log(this.client.hget) ,我会看到:

{ [Function]
      _isMockFunction: true,
      getMockImplementation: [Function],
      mock: [Getter/Setter],
      mockClear: [Function],
      mockReset: [Function],
      mockReturnValueOnce: [Function],
      mockReturnValue: [Function],
      mockImplementationOnce: [Function],
      mockImplementation: [Function],
      mockReturnThis: [Function],
      mockRestore: [Function],
      _protoImpl:
       { [Function]
         _isMockFunction: true,
         getMockImplementation: [Function],
         mock: [Getter/Setter],
         mockClear: [Function],
         mockReset: [Function],
         mockReturnValueOnce: [Function],
         mockReturnValue: [Function],
         mockImplementationOnce: [Function],
         mockImplementation: [Function],
         mockReturnThis: [Function],
         mockRestore: [Function] } }
Run Code Online (Sandbox Code Playgroud)

在我的实际测试中,没有返回任何内容,如果我删除手动模拟 hget 函数,我会在控制台日志中看到相同的内容。我假设任何需要构造函数的模块(而不是“fs”示例)都会存在此问题,因此答案可能是通用的。

jos*_*316 5

事实证明,解决方案非常简单。在我的 ioredis 手册模拟中,我只需要这样做:

// 原始答案

IORedis.prototype.hget = jest.genMockFn();
IORedis.prototype.hget.mockImplementation(function (key, link) {
    // return whatever I want here
});

module.exports = IORedis;
Run Code Online (Sandbox Code Playgroud)

// 最新版本的 Jest

const IORedis = jest.genMockFromModule("ioredis");
IORedis.prototype.hget = jest.fn((key, link) => {
        // return whatever I want here
    });



module.exports = IORedis;
Run Code Online (Sandbox Code Playgroud)