如何在JestJS中使用回调参数模拟函数

李·詹金斯

我的NodeJS应用程序具有一个readFilesJSON()调用函数该函数fs.readFile()当然会调用带参数的回调(err,data)Jest单元测试需要遍历错误路径和数据路径。

我的解决方案是模拟对的调用fs.readFile()(请参见下文)。模拟功能只是根据测试逻辑传递错误或数据。当仅测试一个功能时,此方法有效。我看到的麻烦是在有多个调用函数时发生的fs.readFile()Jest同时运行所有测试,并且这些函数的异步特性意味着对的调用没有保证的顺序fs.readFile()这种不确定的行为会使用破坏错误/数据逻辑和参数检查逻辑toHaveBeenCalledWith()

Jest是否提供一种机制来管理模拟的独立使用?

function readFilesJSON(files,done) {
    let index = 0;
    readNextFile();
    function readNextFile() {
        if( index === files.length ) {
            done();
        }
        else {
            let filename = files[index++];
            fs.readFile( filename, "utf8", (err,data) => {
                if(err) {
                    console.err(`ERROR: unable to read JSON file ${filename}`);
                    setTimeout(readNextFile);
                }
                else {
                    // parse the JSON file here
                    // ...
                    setTimeout(readNextFile);
                }
            });
        }
    }
}

注入的函数设置如下所示:

jest.spyOn(fs, 'readFile')
    .mockImplementation(mockFsReadFile)
    .mockName("mockFsReadFile");

function mockFsReadFile(filename,encoding,callback) {
    // implement error/data logic here
}
呼吸

您可以将不同的场景分为不同的describe块,并在清除观察到的函数的先前调用之后调用函数,以免获得假阳性结果。


import { readFile } from "fs";

import fileParser from "./location/of/your/parser/file";

jest.mock("fs");

// mock the file parser as we want to test only readFilesJSON
jest.mock("./location/of/your/parser/file");

describe("readFilesJSON", () => {
  describe("on successful file read attempt", () => {
    let result;

    beforeAll(() => {
      // clear previous calls
      fileParser.mockClear();
      readFile.mockImplementation((_filename, _encoding, cb) => {
        cb(null, mockData);
      });
      result = readFilesJSON(...args);
    });

    it("should parse the file contents", () => {
      expect(fileParser).toHaveBeenCalledWith(mockData);
    });
  });

  describe("on non-successful file read attempt", () => {
    let result;

    beforeAll(() => {
      // clear previous calls
      fileParser.mockClear();
      readFile.mockImplementation((_filename, _encoding, cb) => {
        cb(new Error("something bad happened"), "");
      });
      result = readFilesJSON(...args);
    });

    it("should parse the file contents", () => {
      expect(fileParser).not.toHaveBeenCalled();
    });
  });
});

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章