Javascript unit testing with Jasmine

@eitanp461

Working @perfectomobile

Why write unit tests?

Verify code correctness

Fast feedback

Assure build quality

Provide documentation for the source code

Uncovering bugs early

It's fun!

 

(Partial list)

Jasmine

Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests

API

Jasmine 2.4 API reference is here

 

          API is coupled with demo code

 

                     don't ignore the tabs on top...

                     try clicking on focused_specs.js link

 

It's pretty cool once you get the hang of it 

Test structure

describe() {
    beforeEach()
    afterEach()
    it() {
        expect().matcher()
    }
}

Suites and specs

describe("Distance Converter", function() {
    it("converts inches to centimeters", function(){
        expect(Convert(12, "in").to("cm")).toEqual(30.48);
    });
})

Suites describe the application under test (aut)

 

Specs are individual tests for aut methods

Focused suites and specs

fdescribe("focused spec", function() {
    fit("focused spec", function(){
        // This spec will run
    });

    it("standard spec", function(){
        // This spec will NOT run
    });
})

Run focused suites and specs to execute only selected tests

 

Don't forget to fail the build if the code is pushed by mistake 

Expectations and matchers

var a = 3;
expect(a).toBe(3);

Expectations are built with the function expect which takes a value, called the actual. It is chained with a matcher function, which takes the expected value.

 

 

Matchers implement a boolean comparison between the actual value and the expected value

Builtin matchers

Jasmine provides a set of builtin matchers:

 

  • toEqual
  • toMatch
  • toBeTruthy
  • toThrow
  • ...

 

 

 

See API reference

Custom matchers

Write expressive custom matchers to fit your needs.

Add them to your suite using addMatchers .

 

 

See custom matchers guide

Spies

Jasmine has test double functions called spies. A spy can stub any function and tracks calls to it and all arguments

 

There are 3 methods for creating spies:

  • spyOn
  • createSpy
  • createSpyObj

Spy creation guidelines

Use spyOn for already existing objects which you need to spy on a specific method, e.g. console.log 

 

 

Use createSpy for functions called by the code under test with no return value, usually callbacks

 

 

Use createSpyObj for interactions of code under test with dependencies, usually other classes

 

See fiddle

Spy training

Now that you’ve created spy functions you can train them to do neat tricks

 

  • and.callThrough
  • and.returnValue
  • and.callFake
  • ...

 

See fiddle

Asynchronous specs

describe("async support", () => {
  it('waits for done to be called', (done) => {
    let a = 3;
    setTimeout(() => {
      expect(a).toBe(6);
      done();
    }, 0);
    a = 6;
  })

  it('resolves promises async', (done) => {
    let promise = new Promise((resolve, reject) => {
      resolve('hooray');
    });
    promise.then((data) => {
      expect(data).toMatch('hooray');
      done();
    })
  })
})

Exercise

More Jasmine goodness waiting for you to discover in the docs

 

 

And since nothing beats hands on experience:

 

Exercise

https://jsfiddle.net/eitanp461/x2zqduzs/

 

Solution

https://jsfiddle.net/eitanp461/2pj1dfxw/

(don't peek)

Thank you

Javascript unit testing with Jasmine

By Eitan Peer

Javascript unit testing with Jasmine

Introduction to unit testing Javascript with Jasmine

  • 2,172