QUnit with Ajax, QUnit passes the failing tests

10,319

Solution 1

Starting and stopping using the QUnit library seems to be working!

// test to check if the persons are returned!
test("getPersons", function() {
  stop();
  getPersons(function(response) {
    persons = $.evalJSON(response.d);
    equals(persons[0].FirstName, "Mohammad");
    start();
  });
});

Solution 2

The real problem here isn't needing to call the start() and stop() methods - in fact you could get into trouble using that approach if you are not careful in calling stop() again at the end of your callback if you have additional .ajax() methods. Which then means you find yourself in some snarled mess of having to keep track if all the callbacks have been fired to know if you still need to call stop() again.

The root of the problem involves the default behavior of asynchronous requests - and the simple solution is to make the .ajax() request happen synchronously by setting the async property to false:

test("synchronous test", function() {
  $.ajax({
    url:'Sample.asmx/Service',
    async:false,
    success: function(d,s,x) { ok(true, "Called synchronously"); }
  });
});

Even still, the best approach is to allow the asynchronous behavior and use the right test method invocation: asyncTest(). According to the docs "Asynchronous tests are queued and run one after the other. Equivalent to calling a normal test() and immediately calling stop()."

asyncTest("a test", function() {
  $.ajax({
    url: 'Sample.asmx/Service',
    success: function(d,s,x) {
      ok(true, "asynchronous PASS!");
      start();
    }
  });
});

Solution 3

There a lot of qunit test in my project. like:

    module("comment");
    asyncTest("comment1", function() {
      expect(6);
      $.ajax({
        url: 'http://xxx.com/comment',
        dataType: "json",
        type: "GET",
        timeout: 1000
      }).done(function(data) {
        ok(true, "loaded");
        ok(data.data.length>1, "array size");
        ok(data.total, "attr total");
        var c = data.data[0];
        ok(c.id, "attr c.id");
        ok(c.user_id, "attr c.user_id");
        ok(c.type == 4, "attr c.type equal 4");
      }).fail(function(x, text, thrown) {
        ok(false, "ajax failed: " + text);
      }).always(function(){
        start();
      });
    });

Solution 4

ive done some qunit testing with ajax. its not pretty. the best thing i could come with is stopping the test when ajax is fired, and starting it again in the success callback. (using start() and stop()) methods. This meant one ajax request at a time, but i could live with that. Good luck

Share:
10,319
azamsharp
Author by

azamsharp

Mohammad Azam is an iOS Instructor at DigitalCrafts. Before joining DigitalCrafts Azam worked as a senior mobile developer at Blinds.com, A Home Depot company. Azam led the mobile team at Blinds.com to develop the Home Depot blinds/shades online experience. Previously, Azam has worked as a team lead for many large companies including Schlumberger, Baker Hughes, AIG and VALIC. Azam has also published 8-10 personal apps to the App Store, including Vegetable Tree - Gardening Guide which was featured by Apple as the best gardening app in the App Store. Azam is also active on YouTube and maintains his popular channel "AzamSharp" where he shares his iOS knowledge. Azam is also a Udemy instructor where he has published courses on "Swift 2.0" and "iOS MapKit Development Using Swift Language". Azam also frequently contributes iOS articles to the Code Magazine and talks at different iOS conferences all around the country. Before entering the iOS community Azam was an active member of the Microsoft .NET community. Azam was also awarded Microsoft MVP award due to his contributions in the .NET community. Azam is also an instructor on Udemy with more than 2000 students. Azam has earned perfect ratings for his courses on Udemy. You can check out Azam's courses using the link below: http://www.azamsharp.com/courses/ When not developing iOS applications Azam likes to spend time with his family and plan his next trip to the unknown corners of the world.

Updated on June 10, 2022

Comments

  • azamsharp
    azamsharp almost 2 years

    I am looking into QUnit for JavaScript unit testing. I am in a strange situation where I am checking against the value returned from the Ajax call.

    For the following test I am purposely trying to fail it.

    // test to check if the persons are returned! 
    test("getPersons", function() {
      getPersons(function(response) {
        // persons = $.evalJSON(response.d);
        equals("boo", "Foo", "The name is valid");
      });
    });
    

    But it ends up passing all the time. Here is the getPersons method that make the Ajax call.

    function getPersons(callback) {
      var persons = null;
    
      $.ajax({
        type: "POST",
        dataType: "json",
        data: {},
        contentType: "application/json",
        url: "AjaxService.asmx/GetPersons",
        success: function(response) {
          callback(response);
        }
      });
    }
    
  • azamsharp
    azamsharp almost 15 years
    Starting and stopping seems to be working! The solution is posted in the post below. Thanks!
  • azamsharp
    azamsharp almost 15 years
    But I wonder why my above approach was not working. I could access the response and everything. It seemed that the equals was failing!
  • mkoryak
    mkoryak almost 15 years
    i think that because of async nature of ajax, the test was finishing before the response came back
  • dbslone
    dbslone over 13 years
    asyncTest(name, ...) is a convenience method for test(name, function() { stop(); ... }). Nesting = bad idea.
  • Goyuix
    Goyuix over 13 years
    @Jörn - thanks for pointing out the nesting. Reading back over this answer I am not sure why I wrapped it in the first place other than to perhaps illustrate you could. I have unwrapped the asyncTest method to make it more clear how it is intended to be used.
  • Giovanni Cappellotto
    Giovanni Cappellotto almost 11 years
    As @Goyuix said you can also use asyncTest() instead of test() to avoid calling the stop() function and to make it explicit that this is an async test.