【问题标题】:How to mock node readline?如何模拟节点readline?
【发布时间】:2019-06-01 06:58:00
【问题描述】:

当用户在 CLI 提示符中输入 y 时,getUserInput 调用一个函数:

export const getUserInput = (fn: () => void) => {
  const { stdin, stdout } = process;
  const rl = readline.createInterface({ input: stdin, output: stdout });
  rl.question("Can you confirm? Y/N", (answer: string) => {
    if (answer.toLowerCase() === "y") {
      fn();
    }
    rl.close();
  });
};

我需要为 getUserInput 模拟 Node 的 readline 创建一个测试。

目前我尝试了以下但没有成功,得到:

TypeError: rl.close is not a function

我的模拟实现是否正确,如果不正确,我该如何解决?

jest.mock("readline");
describe.only("program", () => {
    it.only("should execute a cb when user prompt in cli y", () => {
        const mock = jest.fn();
        getUserInput(mock);
        expect(mock).toHaveBeenCalled();
     });
 });

__mocks__/readline.ts(与node_module相邻的目录)

module.exports ={
  createInterface :jest.fn().mockReturnValue({
    question:jest.fn().mockImplementationOnce((_questionTest, cb)=> cb('y'))
  })
}

【问题讨论】:

  • 没问题!请在这里给minimal reproducible example;你打电话给jest.mock('readline')?在被测代码中是如何导入的?
  • 从我链接到的文档中:"注意:为了正确模拟,Jest 需要 jest.mock('moduleName') 与 require/import 语句在同一范围内。" 不要把它放在规范中。
  • ^ 这个。其实,你可以把它放在规范中,但是你需要重新导入使用模拟模块的模块。
  • 显而易见的路线是不依赖全局readline,并接受readline作为参数(默认),让您轻松通过测试。

标签: javascript node.js typescript jestjs


【解决方案1】:

我能够通过添加一个模拟 close 函数来解决这个问题。

module.exports = {
  createInterface: jest.fn().mockReturnValue({
    question: jest.fn().mockImplementationOnce((_questionTest, cb) => cb("y")),
    close: jest.fn().mockImplementationOnce(() => undefined)
  })
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-14
    • 2014-01-17
    • 2018-12-31
    • 2019-11-03
    • 2020-08-06
    • 1970-01-01
    • 2019-12-09
    • 2019-12-04
    相关资源
    最近更新 更多