如何编写具有异步设置和拆卸操作的测试?

时间:2014-05-01 03:11:26

标签: javascript ajax unit-testing asynchronous qunit

我正在使用一个执行某些异步操作的库(pouchDB)。为了简单起见,我将保留详细信息,因为我认为这是"单元测试"的一般问题。涉及异步操作(用引号进行单元测试,因为如果我测试与其他库的集成,我认为这不是真正的单元测试。但是,使用QUnit似乎是为它编写测试的最合适的方法。)

我正在使用QUnit进行我的js单元测试。我有两个测试。我发现,如果我运行任何一个(同时让另一个注释掉),他们将通过。如果我同时运行它们,则运行第二次的运行将失败。看起来第二个在完成第一个完成之前就已经开始运行,这将阻止第二个设置成功完成。

module("pouchDB integration specs", {

  setup: function(){

   //some setup stuff
    }

  },

  teardown: function(){

   //some teardown stuff    
    });

  }

});

asyncTest("test1", 1, function(){

test1MethodBeingTested();

document.addEventListener("completedTest1Stuff", function(){

      deepEqual(newFriendSchedule, 'new', "Test 1 Looks Good'");
      start();

    });

  });


});

asyncTest("test2", 2, function(){

  stuffBeingTestedForTest2();

  document.addEventListener("test 2 stuff done", function(){

    deepEqual(expectedTest2Result, actualTest1Result, "test 2 looks good!");
    start();    

  })

});

(为废话缩进道歉。无论我多么挣扎,所以编辑不喜欢我)

我查看了Martin Fowler's take on testing asynchronous code,但我从中得到的结果是#34;你应该设计你的代码,以免本身不同步。"这对我没有帮助,因为我正在测试与我不想修改的图书馆的整合(我认为我不应该这样做 - 当然这个问题已经处理好了吗?)

1 个答案:

答案 0 :(得分:1)

与测试方法类似,您可以在拆解代码中使用stopstart来暂停测试运行,直到您的清理代码完成(asyncTest进行隐式调用stop)。 QUnit对stop / start次调用使用计数信号量,因此如果您有多个异步任务,可以多次调用stop

快速举例:

var teardownDone = false;
var tests = 0;

var testContent = function() {
    if (tests > 0) {
        QUnit.ok(teardownDone);
    } else {
        QUnit.ok(true);
        tests++;
    }
};

module('example', {
    teardown: function () {
        // Without this call and the subsequent start(), tests will fail.
        stop();
        setTimeout(function () {
            teardownDone = true;
            start();
        }, 1000);
    }
});

test('test1', testContent);
test('test2', testContent);

JSFiddle