首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何测试inquirer CLIS?

如何测试inquirer CLIS?
EN

Stack Overflow用户
提问于 2019-12-03 12:59:35
回答 1查看 426关注 0票数 1

我想为我在inquirer中制作的CLI编写单元测试。我想验证提示是否正确显示,模拟命令行中的选择,并验证共振是否正确。

EN

回答 1

Stack Overflow用户

发布于 2019-12-03 12:59:35

在尝试了一大堆包,阅读了SO,并做了一些模拟之后,我找到了答案!

首先,您需要创建一个testInquirer.js

代码语言:javascript
复制
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。

testInquirer接口为:

超时命令:用于运行命令行界面的命令(通常类似于进入右目录并运行超时或yarn start)

  • inputs:输入数组,以便发送到标准输入。您可以使用导出的帮助器(ENTERDOWN等),或者输入

pass a CDing,它将侦听所有stdout输出

  • 选项:F116<代码>H117超时:两个命令之间的超时

测试:

代码语言:javascript
复制
import run, { UP, DOWN, ENTER, SPACE } from '../testInquirer';

describe('cli', () => {
  it('runs', async () => {
    const outputMock = jest.fn();

    await run('yarn start', [
      // Choose "Babel Config Generator"
      SPACE,
      DOWN,

      // Choose "CodeFresh Config Generator"
      SPACE,

      // Next Question
      ENTER,

    ], outputMock);

    expect(outputMock).toBeCalledWith(
      expect.stringMatching(/Which Generators do you want to use/)
    );

    expect(outputMock).toBeCalledWith(
      expect.stringMatching(/❯◯ Babel Config Generator/)
    );

    expect(outputMock).toBeCalledWith(
      expect.stringMatching(/❯◯ CodeFresh Config Generator/)
    );

    expect(outputMock).toBeCalledWith(
      expect.stringMatching(/RUNNING GENERATOR: Babel Config Generator/)
    );

    expect(outputMock).toBeCalledWith(
      expect.stringMatching(/RUNNING GENERATOR: CodeFresh Config Generator/)
    );
  })
})

如果你想测试一个接受函数输入的文件,它应该是这样的:

代码语言:javascript
复制
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:/)
    );
  })
})
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59150420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档