How can I write tests that have setup and teardown operations that are asynchronous?

百般思念 提交于 2021-01-28 07:03:09

问题


I am using a library (pouchDB) that does some async operations. To keep things simple, I will keep the details out of it as I think this is a general issue with "unit testing" involving async operations (unit testing in quotation marks because I guess this isn't truly unit testing if I am testing integration with another library. But, using QUnit seems like the most appropriate way to write tests for it).

I am using QUnit to do my js unit testing. I have two tests. I am finding that if I run either one (while having the other commented out) they will pass. If I run both of them together, the run that runs second will fail. It looks like the second one is running before the teardown for the first is complete which stops the setup for the second one from completing successfully.

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

  })

});

(Apologies for the crap indenting. SO's editor doesn't like me no matter how much I wrestle with it)

I had a look at Martin Fowler's take on testing asynchronous code but my takeaway from that was "you should design your code to not be inherently async." Which doesn't help, since I am testing integration with a library which I don't want to modify (nor do I think I should have to - surely this issue has been dealt with before?)


回答1:


Similar to test methods, you can use stop and start in your teardown code to pause the test runner until your clean-up code is done (asyncTest does an implicit call to stop). QUnit uses a counting semaphore for stop/start calls, so you can call stop multiple times if you've got more than one asynchronous task.

Quick example:

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



来源:https://stackoverflow.com/questions/23401474/how-can-i-write-tests-that-have-setup-and-teardown-operations-that-are-asynchron

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!