Jasmine — More Complex Tests

John Au-Yeung - Jan 23 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Testing is an important part of JavaScript.

In this article, we’ll look at how to create more complex tests with Jasmine.

Manually Failing a Spec With fail

We can call the fail function to manually fail a test.

For instance, we can write:

describe("A suite", function () {
  it("should fail", function () {
    fail('failing test');
  });
});
Enter fullscreen mode Exit fullscreen mode

then we see that the test will fail.

Nesting describe Blocks

We can have nested describe blocks to let us describe more complex functionality.

Jasmine will walk down the tree to run the tests that are nested in the same order they’re written in.

beforeEach will run before each test.

And afterEach will run after each test.

For instance, we can write:

describe("A suite", function () {
  let foo;

  beforeEach(function () {
    foo = 1;
  });

  afterEach(function () {
    foo = 0;
  });

  it("foo is 1", function () {
    expect(foo).toEqual(1);
  });

  it("can have more than one expectation", function () {
    expect(foo).toEqual(1);
    expect(true).toEqual(true);
  });

  describe("nested tests", function () {
    let bar;

    beforeEach(function () {
      bar = 1;
    });

    it("can reference both scopes as needed", function () {
      expect(foo).toEqual(bar);
    });
  });
});
Enter fullscreen mode Exit fullscreen mode

We have a describe block that’s nested in another describe block.

The outer ones run first and then the inner ones will run once they’re reached by Jasmine.

Disabling Suites

We can disable suites by using xdescribe .

For instance, we can write:

xdescribe("A spec", function () {
  let foo;

  beforeEach(function () {
    foo += 1;
  });

  it("won't run", function () {
    expect(foo).toEqual(1);
  });
});
Enter fullscreen mode Exit fullscreen mode

We have the xdescribe function to disable the test suite.

So the tests won’t run.

Pending Specs

We can use the xit function to disable a spec so that it won’t run.

For example, we can write:

describe("A spec", function () {
  xit("can be declared 'xit'", function () {
    expect(true).toBe(false);
  });

  it("has no expect");

  it("is pending", function () {
    expect(true).toBe(false);
    pending('this is why it is pending');
  });
});
Enter fullscreen mode Exit fullscreen mode

We have the xit function to make the specs pending.

Also, we can make a spec pending with the pending function.

Spies

We can use spies to stub functions that we can use Jasmine to track calls and arguments.

For instance, we can write:

describe("A spy", function () {
  let foo, bar;
  beforeEach(function () {
    foo = {
      setBar(value) {
        bar = value;
      }
    };
    spyOn(foo, 'setBar');
    foo.setBar('foo');
    foo.setBar(1, 'bar');
  })

  it("tracks that the spy was called", function () {
    expect(foo.setBar).toHaveBeenCalled();
  });

  it("tracks that the spy was called x times", function () {
    expect(foo.setBar).toHaveBeenCalledTimes(2);
  });

  it("tracks all the arguments of its calls", function () {
    expect(foo.setBar).toHaveBeenCalledWith('foo');
    expect(foo.setBar).toHaveBeenCalledWith(1, 'bar');
  });

  it("stops all execution on a function", function () {
    expect(bar).toBeUndefined();
  });

  it("tracks if it was called at all", function () {
    foo.setBar();
    expect(foo.setBar.calls.any()).toEqual(true);
  });
});
Enter fullscreen mode Exit fullscreen mode

We have the beforeEach hook with the foo object with the setBar method.

In the hook, we call the spyOn method to stub the setBar method and then watch how it’s called and the result.

We can use the toHaveBeenCalled matcher to check if the function is called.

Also, we can use toHaveBeenCalledTimes to check how many times it’s been called.

The toHaveBeenCalledWith method lets us check what parameters have the functions been called when they’re called.

calls.any() lets us check if a spied on function has been called.

Conclusion

We can make tests pending and fail with built-in functions.

And we can spy on functions to see how they’re called.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .