Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Test ajax failure with Q-Unit

I'm using jQuery $.when to handle ajax callbacks, and I'm using mockjax to simulate various responses in my unit tests. One of the responses returns a status error of 500. My failure callback throws an error, and in Q-Unit I'm trying to catch that error using "raises" but all I'm getting is the actual error.

Here is the code:

var bar = new Object();  
// ajax call, returns a promise object 
bar.ajaxCall = function () {  
  return $.ajax({
      url: "foo/foo"
      , dataType: "json"
      , data: { "blah": "blee" }    
  }); 
}

// function I'm testing ...
bar.handleAjax = function () {
    return $.when(ajaxCall.call(this))
      .done(function(data) { /* Success callback */ })
      .fail( throw "Error!!"; });
}

Unit test:

// Mock ajax call in the unit test
var mock = $.mockjax({
   url: "foo/foo"
   , contentType: "json"
   , status: 500
});

// unit test for "load"
loadTest = function () {
   test("testing load failure", function () {
      stop(); // stop the test so QUnit knows to wait for the ajax response
      raises(function () {
         var promise = bar.handleAjax();
      }, "We expect an error to be thrown");
      setTimeout(function() { 
         start();
      }, 500);
   });
}

How can I rewrite the test to be sure that handleAjax is throwing an error at the appropriate time?

like image 697
stinkycheeseman Avatar asked Dec 07 '25 20:12

stinkycheeseman


1 Answers

The problem is that calling handleAjax() inside raises() will return immediately and the error will be thrown outside this function.

To solve this you can make the ajax call synchronous and this way the erro will be thrown inside raises().

raises(function () {
  $.ajaxSetup({ async: false });
  bar.handleAjax();
}, "We expect an error to be thrown");

HERE is the working code.

Your problem is that you are throwing a error inside fail() and you cannot easily control when this fail callback will be called and exception will be thrown unless you execute it synchronously. You can rewrote your code that instead of throwing an error you will call a callback.

bar.handleAjax = function(success, error) {
  return $.when(this.ajaxCall.call(this))
    .done(function() { success && success.call(this); })
    .fail(function() { error && error.call(this); });
};

HERE is the example.

Looking forward to better ideas :).

like image 147
kubetz Avatar answered Dec 09 '25 13:12

kubetz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!