QUnit с Ajax, QUnit проходит неудачные тесты

Я изучаю QUnit для модульного тестирования JavaScript. Я нахожусь в странной ситуации, когда я проверяю значение, возвращаемое вызовом 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");
  });
});

Но в итоге все время проходит. Вот метод getPersons, который выполняет вызов Ajax.

function getPersons(callback) {
  var persons = null;

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

person azamsharp    schedule 02.06.2009    source источник
comment
Я бы порекомендовал вам также указать ожидаемое число (второй аргумент QUnit.test), чтобы его было легче поймать, когда не все вызывается вовремя. В противном случае это может быть прохождение, если start вызывается слишком рано, прежде чем все утверждения будут отправлены.   -  person Timo Tijhof    schedule 09.05.2013


Ответы (4)


Запуск и остановка использования библиотеки 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();
  });
});
person azamsharp    schedule 02.06.2009
comment
Как сказал @Goyuix, вы также можете использовать asyncTest() вместо test(), чтобы избежать вызова функции stop() и явно указать, что это асинхронный тест. - person Giovanni Cappellotto; 10.08.2013

Настоящая проблема здесь не в том, чтобы вызывать методы start() и stop() - на самом деле вы можете столкнуться с проблемами, используя этот подход, если вы не будете осторожны при повторном вызове stop() в конце вашего обратного вызова, если у вас есть дополнительные методы .ajax(). Это означает, что вы оказываетесь в запутанном беспорядке, когда вам нужно отслеживать, были ли запущены все обратные вызовы, чтобы узнать, нужно ли вам снова вызывать stop().

Корень проблемы заключается в поведении асинхронных запросов по умолчанию, и простое решение состоит в том, чтобы запрос .ajax() выполнялся синхронно, установив для свойства async значение false:

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

Тем не менее, лучший подход — разрешить асинхронное поведение и использовать правильный вызов метода тестирования: asyncTest( ). Согласно документам, «асинхронные тесты ставятся в очередь и запускаются один за другим. Эквивалентно вызову обычного теста() и немедленному вызову остановки().»

asyncTest("a test", function() {
  $.ajax({
    url: 'Sample.asmx/Service',
    success: function(d,s,x) {
      ok(true, "asynchronous PASS!");
      start();
    }
  });
});
person Goyuix    schedule 05.10.2010
comment
asyncTest(name, ...) — это удобный метод для test(name, function() { stop(); ... }). Вложение = плохая идея. - person Jörn Zaefferer; 12.01.2011
comment
@ Jörn - спасибо, что указали на вложенность. Перечитывая этот ответ, я не уверен, почему я завернул его в первую очередь, кроме как, возможно, проиллюстрировать, что вы могли бы. Я развернул метод asyncTest, чтобы было понятнее, как его предполагается использовать. - person Goyuix; 17.01.2011

В моем проекте много тестов 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();
      });
    });
person Ken    schedule 15.04.2013

Я провел некоторое тестирование qunit с помощью ajax. это некрасиво. лучшее, что я мог сделать, это остановить тест при запуске ajax и снова запустить его в обратном вызове успеха. (используя методы start() и stop()). Это означало один запрос ajax за раз, но я мог с этим смириться. Удачи

person mkoryak    schedule 02.06.2009
comment
Запуск и остановка, кажется, работает! Решение опубликовано в посте ниже. Спасибо! - person azamsharp; 02.06.2009
comment
Но мне интересно, почему мой вышеприведенный подход не работал. Я мог получить доступ к ответу и все такое. Казалось, что равные терпят неудачу! - person azamsharp; 02.06.2009
comment
я думаю, что из-за асинхронной природы ajax тест заканчивался до того, как вернулся ответ - person mkoryak; 02.06.2009