Getting started with Jasmine

To write tests, you should create two things: test suites and specs. A spec (short for specification) is a piece of functionality that you are testing from your code; for example, if your code is calculating tax of 5% for $100.00, you would expect it to be $5. A test suite is a set of expectations that are grouped under a topic. In the preceding example, the test suite can be "Invoice totals calculation".

To start working with Jasmine, you should install it from npm, as follows:

$ npm install --save-dev jasmine

Then, you can start writing your tests. With Jasmine, you have two functions: describe() to create test suites and it() to make specs:

// specs/mathSpec.js	
describe('Basic mathematicfunctions', () => {
it('should result 4 the sum of 2 + 2', () => {
  });

it('should result 1 the substract of 3 - 2', () => {
  });

it('should result 3 the division of 9 / 3', () => {
  });

it('should throw an error when divide by zero', () => {
  });
});

The preceding code defines a test suite for a hypothetical set of math functions. Notice how in the describe() function, you should write a text that tells the people what is the context of the tests; while in the it() function, the text should tells what are you testing.

Now, let's build the math functions for the test suite, as follows:

// app/js/math.js
var math = {
sum(a, b) {
return a + b;
  },

substract(a, b) {
return a - b;
  },

divide(a, b) {
if (b === 0) {
throw new Error('Can not divide by zero');
    }

return a / b;
  }
};

module.exports = math;

The math object has the necessary functions to pass the test suite; however, to actually test the math object, you will need to make a set of expectations.

Expectations

Expectations are functions that compare the output of a function with an expected output. In the following example, we call the sum() function with an input of 2 and 2. We are expecting that the result should be 4:

expect(sum(2, 2)).toEqual(4);

The toEqual()expectation function compares whether the output of the function and the expected value are equal; if both are the same, the test will pass, otherwise, it will fail. The following table shows the most common expectations in Jasmine, consult the documentation for a complete set of available expectation functions:

Expectation function

Description

Example

toEqual

The values should be exactly equal

expect('hello')

.toEqual('hello')

toMatch

The value will be RegEx matched

expect('Hello')

.toMatch(/[Hh]ello/)

toBeTruthy

The value should be a truth value

expect(true)

.toBeTruthy();

expect(100)

.toBeTruthy();

toBeFalsy

The value should be a false value

expect(false)

.toBeFalsy();

expect(null)

.toBeFalsy();

toThrowError

This verifies that the function that is called throws an error

expect(function() {

math.divide(1, 0);

}).toThrowError();

After adding all the expectations to the example test suite that we have, the code should be something as follows:

// spec/mathSpec.js
var math = require('../app/js/math');

describe('Basic mathematic functions', () => {
it('should result 4 the sum of 2 + 2', () => {
expect(math.sum(2, 2)).toBe(4);
  });

it('should result 1 the substract of 3 - 2', () => {
expect(math.substract(3, 2)).toBe(1);
  });

it('should result 3 the division of 9 / 3', () => {
expect(math.divide(9, 3)).toBe(3);
  });

it('should throw an error when divide by zero', () => {
expect(() =>math.divide(9, 0)).toThrowError();
  });
});

To run the test suite, you should first configure the Jasmine test runner. To do this, you should create a script:

// spec/run.js
var Jasmine = require('jasmine');
var jasmine = new Jasmine();

jasmine.loadConfig({
spec_dir: 'spec',
spec_files: [
    '**/*[sS]pec.js'
  ]
});

jasmine.execute();

Jasmine will look for tests under the spec/directory, it will look for all those files that end with spec.js or Spec.js. As our test file is named mathSpec.js, the Jasmine test runner will load and run it, as shown in the following:

$ node spec/run.js
Started
....


4 specs, 0 failures
Finished in 0.008 seconds

You can see what happens if the test fails; for example, you change the sum test to 5 instead of 4:

$ node spec/run.js
Started
F...

Failures:
1) Basic mathematic functions should result 4 the sum of 2 + 2
  Message:
    Expected 4 to be 5.
  Stack:
    Error: Expected 4 to be 5.
at Object.<anonymous>(/path/to/your/project/spec/mathSpec.js:5:28)

4 specs, 1 failure
Finished in 0.009 seconds

Now, if you make a mistake, Jasmine will tell you what's wrong. Notice how Jasmine will inform you about the error:

"Basic mathematic functions should result 4 the sum of 2 + 2"

Then, it tells you that it was expecting 5 and instead received 4. Please note that it is very important what messages you put in the describe() and it() functions as they will help you to quickly diagnose what's wrong.

Testing asynchronous code

When you need to test a code that is asynchronous like an Ajax call, you will need to make an extra step. When you write the it() function, you should pass a done argument and Jasmine will put a callback function there, which you should call when the test is done.

To illustrate this, let's simulate an asynchronous task that sum two numbers, as follows:

var math = {
  // ...

asyncSum(a, b, callback) {
    // Will respond after 1.5 seconds.
setTimeout(function() {
callback(a + b);
    }, 1500);
  },

  // ...
};

Following the JavaScript standard, the syncSum() function receives a third argument, which is the callback function that will be called when the sum is ready. In the following example, the callback function will be called after 1,500 milliseconds:

math.asyncSum(2, 2, result => {
  // After 1500ms result will be equal to 4
});

To make a test with this function, we should pass a done callback to the it() function:

it('sums two numbers asynchronously', done => {
math.asyncSum(2, 2, function(result) {
expect(result).toEqual(4);
done();
  });
});
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.123.73