Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing child_process.exec stdout

I'm trying to test the output of child process with mocha.

My test looks like this:

var should = require("should"),
    exec = require("child_process").exec;

describe('users', function() {
  describe('andrei', function() {
    exec('id andrei', function(error, stdout, stderr) {
      it('should be part of group dev', function() {
        stdout.should.containEql('dev');
      })
    })
  })
})

The problem I'm having is that the it never gets executed.

I could swap the code around, to have the exec inside the it and then use done to ensure things run in the right order, but that would mean I'd have to run the same exec for each test I want to make against the child's stdout.

How can I have multiple it statements against the stdout of a child process?

like image 468
Andrei Serdeliuc ॐ Avatar asked Apr 12 '14 11:04

Andrei Serdeliuc ॐ


1 Answers

Mocha is not designed to run the code you show in your question. You could think of it as running in two phases. In the first phase, it reads all of your test files and executes them. The way it knows what tests you have in your suite is by executing all callback to describe immediately, and each time it encounters it it records is as a test to be run later. In the second phase, it runs the tests. So for a test to be visible to Mocha, it has to have seen an it call for it in the first phase. The code you show will prevent this from happening.

How can I have multiple it statements against the stdout of a child process?

It sounds like you're aiming for one assertion per it. I'm not sure why you want to do this in your specific case. Multiple assertions in the same test is perfectly fine. At any rate, if you must do it then you could use a before hook:

var should = require("should"),
    exec = require("child_process").exec;

describe('users', function() {
    describe('andrei', function() {
        var captured_stdout;

        before(function (done) {
            exec('id andrei', function (error, stdout, stderr) {
                if (error) done(error); // Handle errors.
                captured_stdout = stdout;
                done();
            });
        });

        it('should be part of group dev', function() {
            captured_stdout.should.containEql('dev');
        });
    });
});

The callback passed to before will be run before all the tests in the parent describe. The data to be tested is captured in captured_stdout and then the tests can all access it and test against it.

like image 78
Louis Avatar answered Oct 15 '22 05:10

Louis