spying on node child_process using jasmine

1.2k views Asked by At

I am new to nodejs and jasmine. Working on a small project for learning javascript/node and jasmine. I am trying to spy on the object child_process in node and see the method 'spawn' is called with the arguments specified.

The jasmine error reports that the spawn is never called when the object (Nndb in this case) that invokes the spawn method is called. But the actual work is performed by the child process as I see the results printed in the console.

Here is the failure I see when running the jasmine-node script:

Failures:

1) scrape for xyz spawns child process Message: Expected spy spawn to have been called with [ '../src/scrape_nndb.js', 0 ] but it was >never called. Stacktrace: Error: Expected spy spawn to have been called with [ '../src/scrape_nndb.js', 0 ] but >it was never called. at null. (/Users/arun.bakt/skunkWorks/scraping/spec/nndb_spec.js:30:41) at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

Finished in 6.024 seconds 1 test, 1 assertion, 1 failure, 0 skipped"

The jasmine test file for it:

require('../src/nndb.js');

describe("scrape for XYZ", function() {

    var child = require('child_process');

    it("spawns child process", function() {

        var nndb = new Nndb();
        var child_process =  nndb.child_process;
        spyOn(child_process, "spawn");

        runs(function(){
            flag= false;
            nndb.scrapeForXYZ('../src/scrape_nndb.js', 0);
            setTimeout(function() {
                flag = true;
            },6000)
        });

        waitsFor(function(){
            return flag;
        }, "Scraping done", 6000);

        runs(function(){
            expect(child_process.spawn).toHaveBeenCalledWith('../src/scrape_nndb.js',0);
        });
    });

});

The file nndb.js that is being tested below:

var StringDecoder = require('string_decoder').StringDecoder;

var decoder = new StringDecoder('utf8');

var child_process = require('child_process');

Nndb = function() {

    this.child_process = child_process;

    this.spawn = this.child_process.spawn;

};

Nndb.prototype.scrapeForXYZ = function( phantomScriptToRun, offSet) {


    var child =  this.spawn('phantomjs', [phantomScriptToRun, offSet]);

    child.stdout.on('data',function(data){

         console.log("MATCH "+decoder.write(data));

    });

    child.stderr.on('data', function (data) {
        console.log('stderr: ' + data);
    });

    child.on('exit', function (code) {
        console.log('child process exited with code ' + code);
    });

    return 0;

};



exports.Nndb = Nndb;
1

There are 1 answers

1
user1618143 On BEST ANSWER

Oh, I see the problem. You create nndb, and nndb sets nndb.spawn equal to nndb.child_process.spawn. Then you set a spy on nndb.child_process.spawn, but because nndb.spawn has already been copied off of it, the spy isn't applied to both. When nndb.scrapeForXYZ calls nndb.spawn, the spy is unaffected.

Try this:

it("spawns child process", function() {

    var nndb = new Nndb();
    var child_process =  nndb.child_process;
    spyOn(nndb, "spawn");

    //...
        expect(nndb.spawn).toHaveBeenCalledWith( //...

}