简体   繁体   English

“ it”块执行多次,直到在Jasmine 2.0中调用“ done”为止

[英]'it' block executes multiple times until 'done' is called in Jasmine 2.0

I am creating a test case in Jasmine 2.0 我正在Jasmine 2.0中创建一个测试用例

    describe("TestCase", function(){

        var originalTimeout=0;

        beforeEach(function(){
            originalTimeout=jasmine.DEFAULT_TIMEOUT_INTERVAL;
            jasmine.DEFAULT_TIMEOUT_INTERVAL=10000;
        });

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

        it("check timeout", function(done){
            var startTime=new Date().getTime() / 1000; //line 15
            setTimeout(function(){
                var currentTime=new Date().getTime() / 1000;
                expect(currentTime).toBeGreaterThan(startTime);
                done();
            },5000);
        });
   });

While debugging it I noticed that if we keep a breakpoint at line 15, it gets hit again and again until done in the setTimeout is called. 在调试它时,我注意到,如果我们在第15行保留一个断点,它将断断续续地命中,直到在setTimeout中调用完为止。 Is there any explaination for this behavior? 有这种现象的解释吗? This behavior leads to execution of same test again and again. 此行为导致一次又一次执行相同的测试。

Ok, I've had a good look through the Jasmine source and I see that a lot of work has been done between 1.x -- 2.x -- master in this area. 好的,我对Jasmine源码有了很好的了解,我发现在1.x-2.x-大师之间已经完成了很多工作。

However, I cannot find a loop where the same it gets called again and again waiting for the done() to be called. 但是,我找不到一个循环,在该循环中一次又一次地等待它被调用,并等待done()被调用。

Here is the relevant code from 2.0 : 这是2.0中的相关代码:

  if (fn.length > 0) {
    attempt(function() { fn.call(self, function() {  self.run(fns, index + 1) }) });
  } else {
    attempt(function() { fn.call(self); });
    self.run(fns, index + 1);
  } 

  function attempt(fn) {
    try {
      fn();
    } catch (e) {
      self.onException(e);
      if (!self.catchingExceptions()) {
        //TODO: set a var when we catch an exception and
        //use a finally block to close the loop in a nice way..
        throw e;
      }
    }
  }

You can see that the above code checks to see if there is a done argument fn.length > 0 and then creates the done as the call to execute the next test case. 您可以看到上面的代码检查是否有done参数fn.length > 0 ,然后创建done作为调用以执行下一个测试用例。

This is similar to the code on master (however, master has changed a lot): 这类似于master上的代码(但是master改变了很多):

    for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
      var queueableFn = queueableFns[iterativeIndex];
      if (queueableFn.fn.length > 0) {
        attemptAsync(queueableFn);
        return;
      } else {
        attemptSync(queueableFn);
      }
    }

    function attemptAsync(queueableFn) {
      var clearTimeout = function () {
          Function.prototype.apply.apply(self.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
        },
        next = once(function () {
          clearTimeout(timeoutId);
          self.run(queueableFns, iterativeIndex + 1);
        }),
        timeoutId;

      next.fail = function() {
        self.fail.apply(null, arguments);
        next();
      };

      if (queueableFn.timeout) {
        timeoutId = Function.prototype.apply.apply(self.timeout.setTimeout, [j$.getGlobal(), [function() {
          var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
          onException(error, queueableFn);
          next();
        }, queueableFn.timeout()]]);
      }

      try {
        queueableFn.fn.call(self.userContext, next);
      } catch (e) {
        handleException(e, queueableFn);
        next();
      }
    }

This is largely similar except for a couple changes. 除了几处更改外,这在很大程度上相似。 First, code adds another setTimeout around the async call (and adds a timeout error message). 首先,代码在异步调用周围添加了另一个setTimeout (并添加了超时错误消息)。 Second, the call to the next test case is also wrapped in a call to once : 其次,对下一个测试用例的调用也包含在对once的调用中:

  function once(fn) {
    var called = false;
    return function() {
      if (!called) {
        called = true;
        fn();
      }
    };
  }

The once function makes sure that the test is only called once. once函数可确保测试仅被调用一次。 Which makes me thing that there was a bug in 2.0 (that I don't see) whereby the test was being called again and again. 这让我觉得2.0中有一个错误(我没有看到),该错误一次又一次地调用了测试。

Although inconclusive, this might give you some ideas. 尽管没有定论,但这可能会给您一些想法。 It may be an IDE issue instead of a Jasmine issue. 这可能是IDE问题,而不是Jasmine问题。

Anyway, I hope this helps. 无论如何,我希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM