DhruvAgrawal
DhruvAgrawal

Reputation: 18

Unit testing an Exec stdout event NodeJS

I have below code.

//utils.js
const cp = require('child_process');

module.exports.execuateBashCommand = ()=> {
    return new Promise((resolve, reject)=> {
        try {
            cp.exec('bash bash.sh').stdout.on('data', (response)=> {
                if (response.toString().indexOf("Success") > -1) {
                    //Some business logic
                    const result = "working";
                    resolve(result);
                }
            });
        } catch (error) {
            console.log("Error", error);
            reject(error);
        }
    })
}

Here, there is an anonymous function that gets fired when a data event is emitted by stdout of exec process. I have no control over the output of bash.js, the desired response may take 5 to 10 seconds. Also I cannot add a timer and wait for this event to fire as I have mocked the exec response using sinon. So there is no real call to bash.js. So how can I emit this event manually and see if the business logic get computed? I am new to unit testing in Javascript. Currently I am using mocha and sinon for my unit testing requirements.

I have following test case, but it is not working as expected..

//utils.test.js
 it("1. test case", (done)=> {
        try {
            const mockStdout = new events.EventEmitter();
            mockStdout.on('data', ()=> {
                return "Success";
            });
            mockStdout.emit('data');
            sandbox.stub(cp.exec('test test'), 'stdout').returns(mockStdout);
            utils.execuateBashCommand().then((result)=> {
                assert(data, "working");
                done();
            });
        } catch (error) {
            console.log("Error in test cases: ", error);
        }
    })

Please advice.

Upvotes: 0

Views: 610

Answers (1)

DhruvAgrawal
DhruvAgrawal

Reputation: 18

I have tried couple of things. Finally, my test cases got passed by below solution.

it("1. test case", (done) => {
            const fake = {
                stdout: new EventEmitter(),
            }
            fake.stdout.on('data', () => { });
            sinon.stub(cp, 'exec').returns(fake);
            utils.execuateBashCommand().then((res) => {
                expect(res, true);
                done();
            });
            fake.stdout.emit('data', "Success");
    })

I am not sure whether this is a right way or not. If anyone have better solution, please advice.

Upvotes: 0

Related Questions