What do jasmine runs and waitsFor actually do?

26,204

Solution 1

waitsFor does block until the conditions it's waiting for are met or it times out.

From the jasmine docs: "waitsFor() provides a better interface for pausing your spec until some other work has completed. Jasmine will wait until the provided function returns true before continuing with the next block.".

The linked docs also have a slightly clearer example or waitsFor.

EDIT: Ah I see what you mean now. waitsFor won't block JS that isn't wrapped in runs, waitsFor, ect.

What jasmine is doing is taking the function passed to it via runs or waitsFor and if jasmine is not currently waiting, it executes the function immediately. If it is waiting, it doesn't call it until it's finished waiting.

That doesn't stop the console.log as it's been passed to jasmine so jasmine can't prevent it from being executed straight away.

Solution 2

The solution is in the documentation:

Multiple runs() blocks in a spec will run serially. (Jasmine Documentation)

Solution 3

From the site: http://www.htmlgoodies.com/beyond/javascript/test-asynchronous-methods-using-the-jasmine-runs-and-waitfor-methods.html#fbid=mzNDUVfhFXg

Jasmine will call the runs() and waitsFor() methods in the order you passed them. As soon as the JS parser gets to a waitsFor() method it will poll it until it returns true and only then will it continue onto the next runs() method.

Essentially, the runs() and waitsFor() functions stuff an array with their provided functions. The array is then processed by jamine wherein the functions are invoked sequentially. Those functions registered by runs() are expected to perform actual work while those registered by waitsFor() are expected to be 'latch' functions and will be polled (invoked) every 10ms until they return true or the optional registered timeout period expires. If the timeout period expires an error is reported using the optional registered error message; otherwise, the process continues with the next function in the array. Presumably, expects within the runs() can also trigger a failure report (and perhaps even in the latch functions themselves).

The documentation is particularly obtuse on these asynchronous features.

Share:
26,204
Frederick Roth
Author by

Frederick Roth

Updated on June 08, 2020

Comments

  • Frederick Roth
    Frederick Roth about 4 years

    I use jasmine runs and wait to test asynchronous operations. Everything works fine but I'm not quite sure what goes on behind the scenes.

    The jasmine documentation states the following example to which I added three log statement.

    describe("Asynchronous specs", function() {
      var value, flag;
    
      it("should support async execution of test preparation and exepectations", function() {
    
        runs(function() {
          flag = false;
          value = 0;
    
          setTimeout(function() {
            flag = true;
          }, 500);
        });
    
        waitsFor(function() {
          value++;
          if(flag) {
              console.log("A");
          }
          return flag;
        }, "The Value should be incremented", 750);
    
        console.log("B");
    
        runs(function() {
          console.log("C");
          expect(value).toBeGreaterThan(0);
        });
      });
    });
    

    });

    The first runs and waitsFor are perfectly clear to me. Runs starts an asynchronous operation and waitsFor waits for a condition.

    However I do not understand why the second runs does not start until the waitsFor is finished. The waitsFor is not a blocking call.

    My guess is that waitsFor implicitly blocks any following runs call until it is finished. Is this so?

    My evidence is that the console.log statements output:

    B A C

    But if waitsFor would really block it should be

    A B C

  • Frederick Roth
    Frederick Roth about 11 years
    I'm quite sure that this is not the case. You put a statement between the waitsFor and the second run it will be executed before the code in waitsFor I will update my question to reflect that.
  • Frederick Roth
    Frederick Roth about 11 years
    But thanks for the link to the documentation, I didn't knew it :)
  • Frederick Roth
    Frederick Roth about 11 years
    And thanks again, the answer is in the docs, but not quite where you pointed :)
  • Konstantin K
    Konstantin K over 10 years
    'waitsFor' not only blocks until the condition is met, but also runs the code inside the function passed to it once every 10ms. Useful to keep this in mind. htmlgoodies.com/beyond/javascript/…
  • Florian Neumann
    Florian Neumann about 8 years
    Jasmine 1.3 provides waitsFor-methods (not waitFor) the answer should be corrected.