Muhwu
Muhwu

Reputation: 1181

Node Jasmine 2.0 and multiple conditions

Jasmine has this funky methodology of not halting at a first failure within a test. This is fine in general, but it doesn't come without issues. I'm wondering what the best practice is for a scenario such as this:

it('should process async results nicely', function (done) {
    this.getJSON('something', function(response) {
        expect(response.status).toEqual('ok');
        expect(response.data).toBeDefined();
        expect(response.data.length).toEqual(5);
        done();
    }
}

The problem here is that this will crash the whole test suite if response.data is undefined. Then again, writing conditionals within a test case is generally frowned upon. Do I have any other choice for this scenario? Given the async nature of most of the tests, this is a very common issue.

Upvotes: 0

Views: 558

Answers (3)

Muhwu
Muhwu

Reputation: 1181

The problem was basically that the errors within an AJAX block got thrown out of the context of the it() block and thus, not being caught. The solution was to write some custom error handling within a function that does the AJAX call and have it succeed or fail with the 'done' passed to the it block.

Upvotes: 0

MBielski
MBielski

Reputation: 6620

If you adhered to OAPT (One Assertion Per Test) you would not have this problem (thought you might have others.)

var resp = null;

beforeEach(function(){
    this.getJSON('something', function(response){
        resp = response;
    });
});

it('should have a defined response', function(){
    expect(resp).toBeDefined();
});    

it('should have a status of OK:', function(){
    expect(resp.status).toEqual('ok');
});

it('should have data:', function(){
    expect(resp.data).toBeDefined();
});

it('should have a data length of 5', function(){
     expect(resp.data.length).toEqual(5);
});

This probably isn't 100% accurate on how to handle the variable, but it should give you the general idea. If the first one fails (expecting the resp variable to be defined) you know that your .getJSON function is having a problem. This should work because even though a variable is set to null it is still defined. If your function fails, it will set the variable to be undefined, and thus trip the test.

Upvotes: 1

David Lopez
David Lopez

Reputation: 2247

Maybe something like this could do the trick:

it("should make a real AJAX request", function () {
    var callback = jasmine.createSpy();
    makeAjaxCall(callback);
    waitsFor(function() {
        return callback.callCount > 0;
    }, "The Ajax call timed out.", 5000);

    runs(function() {
        expect(callback).toHaveBeenCalled();
    });
});

function makeAjaxCall(callback) {
    $.ajax({
        type: "GET",
        url: "data.json",
        contentType: "application/json; charset=utf-8"
        dataType: "json",
        success: callback
    });
}

Source: http://www.htmlgoodies.com/beyond/javascript/test-asynchronous-methods-using-the-jasmine-runs-and-waitfor-methods.html#fbid=-1PVhTWm6xy

Upvotes: 0

Related Questions