I have an async function that returns a callback with a status code and path if successful. I would like to use jasmine to test that I receive that status code and have the path be assigned to all future tests. I keep getting an undefined value for my tests...
function make_valid(cb){
var vdt = child.spawn('node', base,
{cwd: ims_working_dir, stdio: ['pipe', 'pipe', 'pipe']},
function (error, stdout, stderr) {
if (error !== null) {
console.log('spawn error: ' + error);
}
});
vdt.stdout.setEncoding('utf8');
vdt.stdout.on('data', function(data) {});
vdt.on('close', function(code) {
if (code === 0) {
cb(null, '/home/');
} else {
cb(null, code);
}
});
}
describe("IMS", function(cb) {
var path;
jasmine.getEnv().defaultTimeoutInterval = 40000;
beforeEach(function(done, cb) {
console.log('Before Each');
path = make_valid(cb);
done();
});
it("path should not be null", function() {
expect(path).toBeDefined();
});
});
Here is the output:
Failures:
1) IMS path should not be null
Message:
Expected undefined to be defined.
Stacktrace:
Error: Expected undefined to be defined.
at null.<anonymous> (/home/evang/Dev/dataanalytics/IMS_Tester/spec/ims-spec.js:46:16)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
Finished in 0.014 seconds
1 test, 1 assertion, 1 failure, 0 skipped
If i get the path passed in the beforeEach declaration I want to write more tests where I parse the file. I think I am dealing with the callbacks incorrectly or maybe I need to use a spy. Let me know!
You are setting path
with the return value of the make_valid
function, yet that function returns nothing.
When I've used jasmine
, I had success with the done()
callbacks only for the tests themselves (the it()
functions).
When needing an asynchronous function before each test, I used their runs()
and waitsFor()
functions.
Try some code like this (modified for your example):
var code = null;
beforeEach( function() {
// get a token so we can do test cases. async so use jasmine's async support
runs( function() {
make_valid( function( error, returnCode ) {
if( error ) code = "ERROR_CODE";
else code = returnCode;
} );
} );
waitsFor( function() {
return code !== null;
} );
runs( function() {
expect( code ).toBeDefined();
} );
} );
afterEach( function() {
code = null;
} );
EDIT:
Based on our comments, a suggested approach for a one-time asynchronous test that applies to other tests down the line would be this sample-spec.js
. The inner tests will not pass if the outer it()
does not use done()
.
/*jslint node: true */
"use strict";
describe( "The full, outer test", function() {
var code = null;
it( "should setup for each inner test", function(done) {
make_valid( function( error, returnCode ) {
expect( returnCode ).toBeDefined();
code = returnCode;
done();
} );
} );
describe( "The inner tests", function() {
it( "inner test1", function() {
expect( code ).not.toBeNull();
} );
it( "inner test2", function() {
expect( code ).toBe(200);
} );
} );
} );
function make_valid( callback ) {
setTimeout( function(){ callback( null, 200 ); }, 500 );
}