Our great sponsors
-
SurveyJS
Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.
-
WorkOS
The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.
There is a CLI application based on Inquirer. Potentially, it could be another CLI library, say something from the following list. Our goal is to provide integration tests. But before that, let's look at the related terminology.
If we talk about the first approach, the following approaches will be useful: Nodejs Child Process: write to stdin from an already initialised process, RobotJS. It makes sense to note here that the approaches above are rather for e2e testing than integration.
original.ts
import { describe, it, expect, beforeEach, afterEach, jest, } from "@jest/globals"; import { Answers } from "inquirer"; import { stdin } from "mock-stdin"; import cli from "./lib"; // We need to import the whole lib module for future mocking. import * as funcModule from "./lib"; // There are key press code sequences to pass them to mocked stdin. const DOWN = "\x1B\x5B\x42"; const ENTER = "\x0D"; describe("Cli", () => { let mockStdin: any; let validatorSpy: any; // Let's spy nameValidator function. const getValidatorSpy = () => jest.spyOn(funcModule, "nameValidator"); // This is a util function const pauseAndSend = async (data: string): Promise => new Promise((resolve) => { process.nextTick(() => { mockStdin.send(data); resolve(); }); }); beforeEach(async () => { // According to https://github.com/caitp/node-mock-stdin?tab=readme-ov-file#modulestdin mockStdin = stdin(); }); afterEach(async () => { // According to https://github.com/caitp/node-mock-stdin?tab=readme-ov-file#mockstdinrestore mockStdin.restore(); validatorSpy.mockRestore(); }); it("should get the correct data on happy flow 1", (done: () => void) => { // The mocked implementation returns valid. It means the validator has been passed the imagined input data. validatorSpy = getValidatorSpy().mockImplementationOnce(() => Promise.resolve(true) ); // Call the main functionality. It expects keyboard input, in this case, from mockStdin's side. // It waits for the input provided in the next block of code. That's why, without this block, the "cli" call below never ends. cli((answers: Answers) => { expect(answers).toStrictEqual({ // The expected result should match with the input below. name: "Foo Bar", iceCream: "Chile", programmingLanguage: "Javascript", }); done(); }); // This block pushes the keyboard input to mocked stdin and allows to finish the block above. (async () => { // Pass for (const command of [ // Enter "Foo Bar" text and press Enter as an answer to the "name" question. "Foo Bar", ENTER, // DOWNx3 and press Enter means "Chile" option for the "iceCream" question. DOWN, DOWN, DOWN, ENTER, // DOWNx2 and press Enter means "Javascript" option for the "programmingLanguage" question DOWN, DOWN, ENTER, ]) { await pauseAndSend(command); } })(); }); });
We use Jest Framework for testing. Jest is not a dogma, and, of course, in its place can be any other test runner, such as Mocha or Ava. Let's focus on tests. I'll provide a short example because I don’t want to waste your time. You can find the full version here. It's crucial to read the comments in the code below. Let's go!
We use Jest Framework for testing. Jest is not a dogma, and, of course, in its place can be any other test runner, such as Mocha or Ava. Let's focus on tests. I'll provide a short example because I don’t want to waste your time. You can find the full version here. It's crucial to read the comments in the code below. Let's go!
We use Jest Framework for testing. Jest is not a dogma, and, of course, in its place can be any other test runner, such as Mocha or Ava. Let's focus on tests. I'll provide a short example because I don’t want to waste your time. You can find the full version here. It's crucial to read the comments in the code below. Let's go!