使用done()测试Jasmine 2.0.0中的异步功能

时间:2015-02-09 11:36:59

标签: asynchronous jasmine

我正在尝试使用done()函数对简单的promise实现(异步代码)实现jasmine测试,虽然正在测试的代码运行得很好,但我的测试失败了。 谁能帮助我弄清楚我的测试中缺少什么?

 var Test = (function () {
    function Test(fn) {
        this.tool = null;
        fn(this.resolve.bind(this));
    }
    Test.prototype.then = function (cb) {
        this.callback = cb;
    };
    Test.prototype.resolve = function (value) {
        var me = this;
        setTimeout(function () {
            me.callback(value);
        }, 5000);
    };
    return Test;
})();

describe("setTimeout", function () {

    var test, newValue = false,
        originalTimeout;
    beforeEach(function (done) {
        originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
        jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;

        test = new Test(function (cb) {
            setTimeout(function () {
                cb();
            }, 5000);
        });
        test.then(function () {
            newValue = true;
            console.log(1, newValue);
            done();
        });
    });

    it("Should be true", function (done) {
        expect(1).toBe(1);

        expect(newValue).toBeTruthy();
    });

    afterEach(function () {
        jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
    });
});

jsfiddle中的相同测试:http://jsfiddle.net/ravitb/zsachqpg/

1 个答案:

答案 0 :(得分:7)

此代码正在测试一个像对象这样的简单承诺,因此为方便起见,会将Test对象称为承诺。

创建承诺后有两个不同的异步事件:  1.调用.then()方法  2.通过调用cb()函数中的beforeEach()函数来解析承诺。

在现实世界中,这两个可以在任何时间以任何顺序被调用。

对于测试,必须将.then()调用移至it()部分的回调,并且需要在其中调用所有规范方法(例如expect())&#39 ; s回调或他们会在解决之前运行。 beforeEach()是测试设置的一部分,而it()函数是规范,即测试本身。

done()方法需要调用两次,

  1. beforeEach()异步操作完成时(即调用cb()之后),将开始运行规范。所以看起来应该是这样的:

      beforeEach(function (done) {
        test = new Test(function (cb) {
            setTimeout(function () {
                console.log("in beforeEach() | setTimeout()");
                cb(resolvedValue);
                done()
            }, 500);
        });
      });
    
  2. 在调用jasmine测试方法之后,在it()方法内完成规范(.then()部分的)异步操作时,这将告诉Jasmine规范已完成运行(因此无法达到超时)。所以:

    it("Should be " + resolvedValue, function (done) {
        test.then(function (value) {
            console.log("in then()");
            expect(value).toBe(resolvedValue);
            done();
        });      
    });
    
  3. 另外,正如您所看到的那样,我没有测试变量值的变化,而是测试传递给.then()方法的值与传递给promise的值相同解决cb()函数,因为这是您期望的正确行为。

    这是你小提琴的updated version

    您可以在浏览器的控制台中查看是否正在调用所有回调

    注意:更改Jasmine的DEFAULT_TIMEOUT_INTERVAL只会让它更加复杂,所以我删除了它和一些无关的代码。