我正在使用做一些异步操作的库(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();

  })

});


(为垃圾缩进而道歉。无论我怎么努力,SO的编辑都不喜欢我)

我看了Martin Fowler's take on testing asynchronous code,但是我的收获是“您应该设计代码,使其本质上不异步”。这无济于事,因为我正在测试与我不想修改的库的集成(我也不认为我必须这样做-确实已经解决了此问题?)

最佳答案

与测试方法类似,您可以在拆卸代码中使用stopstart暂停测试运行程序,直到完成清理代码为止(asyncTeststop进行隐式调用)。 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

09-18 06:14
查看更多