cocoa
cocoa

Reputation: 3921

Get Frisby.js tests to run synchronously

I have these API calls in my test that need to run first so I can store the response in a variable to use later. But it looks like my tests are running asynchronously so the second test finishes before the variable gets populated. How can I make the tests run synchronously?

I've heard that one way is to use before and passing the done callback. But I'm not sure how to do that with jasmine-node.

Example of test:

var dataID = '';
frisby.create('Get ID')
  .get(url)
  .expectStatus(200)
  .afterJSON(function(json) {
     dataID = json.id;
  })
.toss();

frisby.create('Get data with ID')
  .get(url, id)
  .expectStatus(200)
  .expectJSON({"id": dataID})
.toss();

EDIT:

So I tried doing my test like this and the done() callback doesn't seem to get called. (The test times out)

describe('API TEST', function() {
  beforeEach(function(done) {
    frisby.create('Get ID')
      .get(url)
      .expectStatus(200)
      .afterJSON(function(json) {
        dataID = json.id;
        done();  //?
      })
      .toss()
  });
  it('should work', function() {
    console.log('TEST');
  }); //"timed out after 5000 msec waiting for spec to complete"
});

Upvotes: 2

Views: 2003

Answers (4)

vvg
vvg

Reputation: 51

I did smaller modification for me in this function but this works for adding node with escape character in xml

private void somefunctToReplaceTxtinExistingNode(Node tempNode, String texttobeSet){
    String newtext = "<" + tempNode.getNodeName() + ">" + texttobeSet + "</" + tempNode.getNodeName() + ">";
    // create of new temp document .node will be imported from this
    DocumentBuilderFactory dbf = ....
    DocumentBuilder builder = ..
    Document newDoc = builder.parse(new StringBufferInputStream(texttobeSet));

    Node nodeXmlWithEscapeChars = newDoc.getFirstChild();
    // Import the node in old doc
    Document document = tempNode.getOwnerDocument();
    Node impNode = document.importNode(nodeXmlWithEscapeChars, true);
    // lastly . delete old with 
    Node parent = tempNode.getParentNode();
    parent.removeChild(tempNode);
    parent.appendChild(impNode);
}

Upvotes: 0

TaraC
TaraC

Reputation: 21

This is a little late but in case someone else might have the same question. You can nest the second test into the afterJson() of the first test like this to make sure it runs after the first one is done

frisby.create('Get ID')
  .get(url)
  .expectStatus(200)
  .afterJSON(function(json) {
     var dataID = json.id;
     frisby.create('Get data with ID')
        .get(url, id)
        .expectStatus(200)
        .expectJSON({"id": dataID})
    .toss()
  })
.toss();

Upvotes: 1

cocoa
cocoa

Reputation: 3921

What I ended up doing was using the async library and doing .timeout(60000) on the actual frisby test like so:

async.series([
  function(cb) {
    frisby.create('Get ID')
      .get(url)
      .expectStatus(200)
      .afterJSON(function(json) {
        dataID = json.id;
        cb();
      })
      .toss();
  },
  function() {
     //other tests using id
  }
]);

Upvotes: 4

Cymen
Cymen

Reputation: 14419

Jasmine handles asynchronous tests by passing a special done parameter to the test function as an argument -- you have to call done (ie done()) when the asynchronous part finishes.

Here is an example test using done:

describe('my test', function() {
  it('completes on done', function(done) {
    var a = 10;

    // this would normally be a call to the code under test
    setTimeout(function() {
      a = 20;
    }, 250);

    setTimeout(function() {
      expect(a).toEqual(20);
      done();
    }, 1000);
  });
});

In the case of frisby.js, it appears that asynchronous testing is surprisingly still an issue. See the issues on the github repo:

open frisby issues involving async

Upvotes: 3

Related Questions