Search code examples
jasminejasmine-node

Jasmine - Multiple it's, one asynchronous call


Scenario

I'm trying to do multiple it specs on a single external load rather than have the external data loaded EVERY time.

Question

How can I do this with a single call of getExternalValue while still keeping my it definitions?

Ideas

Currently I'm doing all the expects in a single it block. I've also thought about storing the loaded value before my tests but then I'd have to find another way to make jasmine wait until the value is loaded.

Code

function getExternalValue(callback) {
    console.log("getting external value");
    
    setTimeout(function() {
        callback(true);
    }, 2000);

    return false;
}

describe("mjaTestLambda()", function() {
    it("is truthy", function(done) {
        let truthy;
        truthy = getExternalValue(function(bool) {
            truthy = bool;
            expect(truthy).toBeTruthy();
            done();
        });
    });

    it("is falsy", function(done) {
        let truthy;
        truthy = getExternalValue(function(bool) {
            truthy = bool;
            expect(!truthy).toBeFalsy();
            done();
        });
    });
});

Solution

  • How can I do this with a single call of getExternalValue while still keeping my it definitions?

    Use beforeEach() or beforeAll() to get the resolved value. Personally I suggest beforeEach() as it will reset the value for each test and helps ensure a clean setup for each one.

    I noticed your function has a callback parameter. Async/await is a useful pattern that works best when (1) you're writing async/await functions or (2) your functions return a Promise. If you need to keep the callback parameter, let me know and I'll update the following:

    // returns Promise
    function getExternalValue() {
      return new Promise((resolve, reject) => {
        console.log("getting external value");
        setTimeout(() => {
          resolve(true);
        }, 2000);
      });
    }
    
    describe("mjaTestLambda()", () => {
    
        let value;
    
        beforeAll(() => {
          return getExternalValue()
            .then((v) => { value = v; });
        });
    
        it("is truthy", () => {
          expect(v).toBeTruthy();
        });
    
        it("is not falsy", () => {
          expect(!v).toBeFalsy();
        });
    });