【问题标题】:Jest - mocking zlib function which is wrapped in promisify does not work开玩笑 - 包含在 promisify 中的模拟 zlib 函数不起作用
【发布时间】:2021-08-01 04:00:01
【问题描述】:

我正在尝试测试一个使用 zlib 的文件,该文件包含在 promisify 中,但是当测试到达代码中使用 zlib 的行时,我得到一个开玩笑的超时错误。

: Timeout - Async callback was not invoked within the 30000 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 30000 ms timeout specified by jest.setTimeout.Error:

模块文件:

import zlib from 'zlib';
import util from 'util';
const zlibGunzip = util.promisify(zlib.gunzip);

async function unzipObjectContent(objectBody): Promise<string> {
    const buff = objectBody as Buffer;
  
    try {
      const data = await zlibGunzip(buff);
      const utf8String = data.toString('utf8');
      const parsedJson = JSON.parse(utf8String);
  
      return JSON.stringify(parsedJson);
    } catch (error) {
      logger.error(`unzipObjectContent -> failed to unzip file ${error}`);
      throw error;
    }
  }

测试文件

jest.mock('zlib');
import zlib from 'zlib';

let gunzipMock: jest.SpyInstance;
gunzipMock = jest.spyOn(zlib, 'gunzip');
gunzipMock.mockResolvedValue(JSON.stringify(problemZipContent));

当我调试测试时,我看到它到达了对await zlibGunzip(buff); 的调用,但随后抛出了一个错误。它也没有到达 catch 块。

请告知我该如何测试。 谢谢

【问题讨论】:

    标签: node.js typescript jestjs mocking es6-promise


    【解决方案1】:

    模拟zlib.gunzip() 方法及其实现,由于该方法的第二个参数是Node.js 错误优先回调,您需要在测试中手动调用callback 函数。这样util.promisify(zlib.gunzip)返回的promise就会被解析。

    例如

    index.ts:

    import zlib from 'zlib';
    import util from 'util';
    
    const zlibGunzip = util.promisify(zlib.gunzip);
    
    export async function unzipObjectContent(objectBody): Promise<string> {
      const buff = objectBody as Buffer;
    
      try {
        const data = await zlibGunzip(buff);
        const utf8String = data.toString('utf8');
        const parsedJson = JSON.parse(utf8String);
    
        return JSON.stringify(parsedJson);
      } catch (error) {
        console.error(`unzipObjectContent -> failed to unzip file ${error}`);
        throw error;
      }
    }
    

    index.test.ts:

    import zlib from 'zlib';
    import { unzipObjectContent } from './';
    import { mocked } from 'ts-jest/utils';
    
    jest.mock('zlib');
    
    const mzlib = mocked(zlib);
    
    describe('67475685', () => {
      afterAll(() => {
        jest.resetAllMocks();
      });
      it('should pass', async () => {
        const problemZipContent = Buffer.from(JSON.stringify({ name: 'teresa teng' }));
        mzlib.gunzip.mockImplementationOnce((buffer, callback: any) => {
          callback(null, problemZipContent);
        });
        const actual = await unzipObjectContent(problemZipContent);
        expect(actual).toEqual('{"name":"teresa teng"}');
        expect(mzlib.gunzip).toBeCalledTimes(1);
      });
    });
    

    测试结果:

     PASS  examples/67475685/index.test.ts (7.156 s)
      67475685
        ✓ should pass (4 ms)
    
    ----------|---------|----------|---------|---------|-------------------
    File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    ----------|---------|----------|---------|---------|-------------------
    All files |   83.33 |      100 |     100 |   83.33 |                   
     index.ts |   83.33 |      100 |     100 |   83.33 | 16-17             
    ----------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        7.656 s, estimated 8 s
    

    【讨论】:

    • 感谢@slideshowp2 很好的回答!!
    猜你喜欢
    • 1970-01-01
    • 2020-10-01
    • 2018-04-29
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 2021-02-07
    相关资源
    最近更新 更多