在玩笑的readline模块的回调内部做断言

时间:2018-10-13 09:39:32

标签: node.js jestjs

我正在尝试在处理用户输入的回调中测试一些内容。我在Jest中使用nodejs中的readline模块(类似于文档中给出的the example)。我不知道如何在该回调中进行断言。

例如:在readline.createInterface().question()的回调中,我正在呼叫writeFileSync。我想测试如何是否 writeFileSync(或回调中的任何其他函数)被调用。

// file.js
const { writeFileSync } = require('fs');
const readline = require('readline');

const copyFile = () => {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    rl.question('What is the file name?', (userInput) => {
        /**
         * I want to some assertions on this function.
         * For example: with which arguments was it called?
         * Or how often is it called?
         */
        writeFileSync();
    });
}

在测试中

//file.test.js
const { writeFileSync } = require('fs')
jest.mock('fs');

describe('copies files based on user input', () => {
    test('calls writeFileSync', () => {
        expect(writeFileSync).toHaveBeenCalled();
    });
});

我最接近的是:

// __mocks__/readline.js

module.exports = {
    createInterface: jest.fn().mockReturnValue(
        {
            question: jest.fn().mockImplementation(
                (question, cb) => {
                    writeFileSync()
                }
            )
        }
    )
}

但是我注意到我正在测试测试。有人知道我如何测试rl.question()回调函数中的内容吗?如有必要,我会很乐意提供更多信息!

2 个答案:

答案 0 :(得分:1)

这就是所谓的测试间谍,Sinan.Js有很多帮助者, 检查the docs for examples

在这里,我们可以在运行此测试之前监视fs.writeFileSync,然后在测试中使用该间谍。

const spy = sinon.spy(writeFileSync);

然后您可以使用spy properties对间谍电话进行断言,例如:

 spy.callCount
 spy.calledWith()
 spy.calledOn()

答案 1 :(得分:1)

我找到了它:它需要模拟实现并调用回调参数(在这种情况下为cb

// __mocks__/readline.js
module.exports = {
    createInterface: jest.fn().mockReturnValue({
        question: jest.fn()
            .mockImplementationOnce((questionText, cb) => {cb('')}) // test empty arg
            .mockImplementationOnce((questionText, cb) => {cb('foo')})
            .mockImplementationOnce((questionText, cb) => {cb('bar')})   
        })
    })
};

返回''foobar作为模拟的用户输入值。