QUnit与Ajax,QUnit通过了失败的测试

14

我正在学习JavaScript单元测试的QUnit。我现在处于一个奇怪的情况,需要检查从Ajax调用返回的值。

对于以下测试案例,我故意尝试使其失败。

// 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");
  });
});

但最终它总是通过的。这是进行Ajax调用的getPersons方法。

function getPersons(callback) {
  var persons = null;

  $.ajax({
    type: "POST",
    dataType: "json",
    data: {},
    contentType: "application/json",
    url: "AjaxService.asmx/GetPersons",
    success: function(response) {
      callback(response);
    }
  });
}

我建议您也填写“expect”数字(QUnit.test的第二个参数),这样当不是所有内容都按时调用时,就更容易捕获。否则,如果在发送所有断言之前太早调用了“start”,则可能会通过测试。 - Timo Tijhof
4个回答

25

似乎使用QUnit库进行启动和停止是有效的!

// 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();
  });
});

1
正如@Goyuix所说,您也可以使用asyncTest()而不是test()来避免调用stop()函数,并明确这是一个异步测试。 - Giovanni Cappellotto

13

问题的真正症结不在于需要调用start()和stop()方法 - 实际上,如果您在回调函数中不小心再次调用stop()方法并且还有其他的.ajax()方法,则可能会遇到麻烦。这意味着你会陷入一些混乱的困境,必须跟踪所有回调是否已经触发,以知道是否仍然需要再次调用stop()方法。

问题的根源涉及异步请求的默认行为 - 简单的解决方法是通过将async属性设置为false使.ajax()请求同步进行:

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

即使如此,最好的方法是允许异步行为并使用正确的测试方法调用:asyncTest()。根据文档,“异步测试被排队并依次运行。相当于调用普通test()并立即调用stop()。

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

asyncTest(name, ...) 是一个方便的方法,用于测试(name, function() { stop(); ... })。嵌套=不好的想法。 - Jörn Zaefferer
@Jörn - 感谢您指出嵌套的问题。回顾这个答案,我不确定为什么要将其包装起来,除了可能是为了说明您可以这样做。我已经取消了asyncTest方法的包装,以使其更清晰地表明它的预期用途。 - Goyuix

3

我的项目中有很多QUnit测试,例如:

    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();
      });
    });

2

我已经用QUnit对Ajax进行了一些测试,但结果不是很理想。最好的解决方法是在Ajax被触发时停止测试,并在成功回调中重新启动测试(使用start()和stop()方法)。这意味着每次只发送一个Ajax请求,但我可以接受这种情况。祝你好运!


开始和停止似乎正在工作!解决方案已发布在下面的帖子中。谢谢! - azamsharp
但我不知道为什么我的上述方法没有起作用。我可以访问响应和所有内容。似乎等号失败了! - azamsharp
2
我认为由于Ajax的异步特性,测试在响应返回之前就已经完成了。 - mkoryak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接