Jestjs 如何测试查询器CLIS?
我想为我在inquirer中制作的CLI编写单元测试。我想验证提示是否正确显示,在命令行中模拟选择,并验证响应是否正确。在尝试了一系列程序包、阅读了这些内容并进行了模拟之后,我找到了答案 首先,您需要创建一个Jestjs 如何测试查询器CLIS?,jestjs,inquirer,Jestjs,Inquirer,我想为我在inquirer中制作的CLI编写单元测试。我想验证提示是否正确显示,在命令行中模拟选择,并验证响应是否正确。在尝试了一系列程序包、阅读了这些内容并进行了模拟之后,我找到了答案 首先,您需要创建一个testinquire.js import { writeFileSync, unlinkSync } from "fs"; import * as child_process from "child_process"; const TEMP_FILE_PATH = "/tmp/"; e
testinquire.js
import { writeFileSync, unlinkSync } from "fs";
import * as child_process from "child_process";
const TEMP_FILE_PATH = "/tmp/";
export default async (
command,
inputs,
{ output, error },
{ timeout, nodeScript, nodeCommand } = {
timeout: 100,
nodeScript: false,
nodeCommand: "node"
}
) =>
new Promise(async resolve => {
let proc;
let tmpFile = `${TEMP_FILE_PATH}${Math.random()}.js`;
if (nodeScript) {
writeFileSync(tmpFile, command);
proc = child_process.exec(`${nodeCommand} ${tmpFile}`);
} else {
proc = child_process.exec(command);
}
proc.stdout.on("data", data => {
output(data);
});
proc.stderr.on("data", data => {
error(data);
});
const sendKeys = async inputs => {
await inputs.reduce(
(previousPromise, input) =>
new Promise(async resolve => {
if (previousPromise) {
await previousPromise;
}
setTimeout(() => {
proc.stdin.write(input);
resolve();
}, timeout);
}),
null
);
proc.stdin.end();
};
await sendKeys(inputs);
proc.on("exit", code => {
if (nodeScript) {
unlinkSync(tmpFile);
}
resolve(code);
});
});
// https://www.tldp.org/LDP/abs/html/escapingsection.html
export const DOWN = "\x1B\x5B\x42";
export const UP = "\x1B\x5B\x41";
export const ENTER = "\x0D";
export const SPACE = "\x20";
然后,您可以测试您的CLI
TestInquire的api是:
- command:用于运行CLI的命令('通常类似于CDing到right dir并运行
或节点。
)纱线开始
- 输入:发送到标准输入的输入数组。您可以使用导出的帮助程序(
、输入
等)或输入向下
- 输出:传递一个将侦听所有标准输出的
jest.fn()
- 选择:
- 超时:命令之间的超时
describe(runGenerator, () => {
let outputMock;
let errorMock;
beforeEach(() => {
outputMock = jest.fn();
errorMock = jest.fn();
});
it.only('runs a generator', async () => {
const runGeneratorPath = `${__dirname.replace(/(\s+)/g, '\\$1')}/../runGenerator.ts`;
const code = await testInquirer(`
const runGenerator = require("${runGeneratorPath}").default;
console.error(runGenerator)
runGenerator(${JSON.stringify(MOCK_GENERATOR)});
`, [], { output: outputMock, error: errorMock }, {
nodeScript: true,
nodeCommand: 'ts-node'
});
expect(code).toBe(0);
expect(outputMock).toBeCalledWith(
expect.stringMatching(/RUNNING GENERATOR: Mock Generator/)
);
expect(outputMock).toBeCalledWith(
expect.stringMatching(/Executing step:/)
);
})
})
describe(runGenerator, () => {
let outputMock;
let errorMock;
beforeEach(() => {
outputMock = jest.fn();
errorMock = jest.fn();
});
it.only('runs a generator', async () => {
const runGeneratorPath = `${__dirname.replace(/(\s+)/g, '\\$1')}/../runGenerator.ts`;
const code = await testInquirer(`
const runGenerator = require("${runGeneratorPath}").default;
console.error(runGenerator)
runGenerator(${JSON.stringify(MOCK_GENERATOR)});
`, [], { output: outputMock, error: errorMock }, {
nodeScript: true,
nodeCommand: 'ts-node'
});
expect(code).toBe(0);
expect(outputMock).toBeCalledWith(
expect.stringMatching(/RUNNING GENERATOR: Mock Generator/)
);
expect(outputMock).toBeCalledWith(
expect.stringMatching(/Executing step:/)
);
})
})