What's This Course About?

Understand what to expect from this course and what the prerequisites are. Get introduced to Jasmine unit testing.

Getting started

This course will cover details about unit testing, ranging from trivial functions to higher-order functions to promises. We’ll cover what tools Jasmine affords and how to utilize them. Though you may be uncertain how to use unit tests now, we’ll help you discover their utility and helpful functionality.

Becoming a capable unit tester will help you:

  • Be confident in the code you write.

  • Discover bugs long before Quality Assurance (QA) or your users do.

  • Understand what to test and what to skip.

  • Grok your code better.

  • Understand code authored by others.

  • Feel comfortable with unit testing anything, be it a function or a full-blown SPA component.

This is a journey anyone can take on their own. Or better yet, we can start it together with this course!

We’ll take this journey step-by-step. Along the way, you’ll write lots of code and learn through examples.

What to expect

In most lessons, there’s a function (or a few) that’s the main subject and is tested. We’ll review the function and show its logic, often line by line. Then, there’s a code playground with the function and its tests. Finally, there is an exercise section where a code playground has a similar function and test file set up that we can use to apply the lesson’s concepts.

Note: Though some of the exercises might seem very simple to you, you’ll get the most out of this course if you actually try them!

Requirements

You’ll need some basic JavaScript knowledge to get the most out of this course. If you don’t feel ready yet, consider taking this JavaScript course.

Let’s go!

Let’s go and experience unit testing with the example below.

Our goal is to get a feeling of what a test suite looks like. Don’t worry if you don’t understand something—we’ll dive deep into every aspect of unit tests in the lessons ahead.

The function

The function is an implementation or polyfill for the Array map function. It does the following:

  • It takes an array and a function (projection) as the input.
  • It passes every member of the array as the input to the function.
  • It creates a new array with the results of the function call.

(For details about map, check out MDN)

function map(arr, cb) { ... }

var numbers = [1,2,3];
var doubled = map(numbers, x => x * 2);
// Doubled === [2,4,6];

In the code example above, we take numbers as the input and use the map function to double each member of the array. The code starts with [1, 2, 3] and results in an output of [2, 4, 6].

Code playground

We can try it out ourselves. Unit test the map function in the code playground below.

Run the code by pressing the “Run” button below the code and checking the terminal below it.

We can make changes in the code. Press the “Run” button to see how they affect the outcome.

/**
 * Map function (A replacement for Array.prototype.map) takes an array, maps over its items, and returns a new array
 * @param {Array} arr the array to iterate over and project each item via the projection arg
 * @param {(x: any) => any} projection the projection function that receives an item and returns an item
 */
function map(arr, projection) {
    const result = [];
    for (let i = 0; i < arr.length; i++) {
        const next = arr[i];
        result.push(projection(next));
    }
    return result;
}

exports.map = map;
A function test suite

We see information about four passing tests in the terminal output of the code playground.

Breakdown

What we see in the code widget above is a minimal test suite comprising two files.

The first file is src/map.js. This file houses the implementation of the function. It takes an array and a function, applies the function to each member of the array, and creates a new array with the results.

The second file is src/map.spec.js.This houses the testing framework:

  • The line const map = require('./map'); imports the map function in the test module so tests can see it.

  • The describe function denotes a test suite for Jasmine (the tool that runs the tests). It has a name and a function implementation.

  • The it function denotes a test case. It has a name and a function implementation.

    There are four unit test cases covered here that:

  • double each array’s member.

  • extract the lengths of each string in an array.

  • verify that map works with empty arrays.

  • verify that map throws an empty array. Each test case follows a simple pattern: get an output from the function being tested, and compare it with the expected output.

Note: The output is often referred to as the actual output and compared to the expected output.— That’s the essence of unit testing.

The spec/support folder contains the configuration for Jasmine that we’ll get into later.

Experiment

Experiment with the code widget. Edit files and hit the “Run” button to see how the change reflects in the output.

For example, try the following:

  1. In src/map.spec.js, change the first it calls to fit and run the code. Notice how just that one test runs while the rest are skipped.

  2. In src/map.js, simulate a bug/regression by changing the implementation and run. Notice how the tests are red, effectively catching the bug/regression.

  3. At line 8 of src/map.js, change let i = 0 to let i = 1 and see failing tests.

Go ahead and experiment. We can always revert to the original code using the “Reset” button.