Jasmine — More Complex Tests
Tags: webdev, programming, javascript, tutorial
Published: 2021-01-23 20:51:27

**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');
  });
});
```

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);
    });
  });
});
```

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);
  });
});
```

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');
  });
});
```

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);
  });
});
```

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.