.NET Tools How-To's Testing

Unit Testing in TypeScript Code

We all need to unit test our code to verify that it works the way it’s supposed to. Fortunately, Rider has the tools to enable you to test code more efficiently and quickly. In this post, we’ll look at using Mocha and Chai to write unit tests in TypeScript.

Unit Testing Overview

Unit testing is a testing technique that targets the smallest discrete units of code, which are functions. Hence the name, “unit testing”. The purpose of unit testing is to verify that the unit of code does exactly what it’s supposed to.

For example, if a function is supposed to calculate the sum of two numbers, a unit test can be written to verify that it does indeed do that correctly. Each unit is tested separately and independently of other units. Essentially, unit tests are code that runs other code to verify that the code it just ran works properly.

Some developers write the code, then write the tests. Others use the TDD (Test Driven Development) approach to testing, meaning that they write the test first and then the code. Using the TDD approach, you typically take a look at your requirement, shape how it should behave by writing a test which will fail, then modify the code so that you get a passing test. After that, you may want to refactor and clean up the code and test.

Unit Testing Frameworks: Mocha and Chai

If you’re new to unit testing, it may seem daunting to go combing through Google looking for a great framework. No worries though – most unit testing frameworks have similar features, though you may find one that has a feature that you prefer. So it’s a good idea to invest a few minutes reviewing some of the popular ones, to find which suits you best. Once you’ve used one framework, try another that has some small differences. A few popular frameworks are shown below for you to explore:

Rider fully supports unit testing in TypeScript/JavaScript, including coverage metrics. You can install, configure, write, and run tests all from within Rider. Mocha.js is a unit testing framework for JavaScript and TypeScript, and Chai is an assertion library that works in tandem with any JavaScript testing framework. Chai leans more toward BDD (Behavior-Driven-Development); however, it contains assertions for both TDD and BDD style testing. BDD emerged from TDD, and uses human-readable descriptions of software requirements as the basis for the tests.

These two frameworks make a great unit testing team, so let’s try them out.

Project Configuration

You can use npm or Yarn to install any TypeScript or JavaScript library in the Terminal window in Rider. Alternatively, you can enter the package name and version into the package.json file. Add a project.json file to the project by using Ctrl + N and typing package.json.

Add a new package.json file

Add the entries typescript and ts-node under the dependencies node, press Alt+Enter, and accept Rider’s suggestion to Run npm install. This adds the packages to a node_modules directory under your project. Using Rider’s built-in autocomplete features reduces typos and errors, making the experience smooth.

Install npm packages

Install Mocha, Chai, and their TypeScript type libraries the same way. Their entries belong under the devDependencies node. Below is a sample using the latest version of the libraries at the time this article was published.

"devDependencies": {
  "@types/mocha": "7.0.2",
  "@types/node": "14.0.11",
  "@types/chai": "4.2.11",
  "chai": "4.2.0",
  "mocha": "7.2.0"
}

Once configuration is complete, onto writing the tests and code!

Write Unit Tests in TypeScript

The testing frameworks and the code you want to test must be imported. Import statements belong at the top of the file.

import { describe } from 'mocha';
import { expect } from 'chai';
import { TaxCalculator} from "./taxCalculator";

Rider helps you by showing autocomplete options, then filling in the details, such as TaxCalculator for the class in the taxCalculator.ts file. All you do is start typing, and select an option.

Import test libraries and code to test

In TypeScript, functions are contained within classes, but they may also stand alone. Mocha’s describe function allows you to group code together for testing – perhaps all the methods of a class, or a group of stand-alone functions. While it’s not mandatory, grouping related logic is quite useful and makes tests easier to maintain.

As an example, to group a Calculator class that contains Add, Subtract, Multiply, and Divide methods, add a describe function and supply a string value describing the group of tests. Additionally, it’s a good idea to add individual describe methods for each test or set of test cases within the group. The code will look similar to the following sample:

describe('Calculations from Calculator class', () => {
  describe(‘add two numbers', () => {
    // test cases here 
  });
  describe('subtract two numbers', () => {
    // test cases here
  });
  describe('multiply two numbers', () => {
    // test cases here
  });
  describe('divide two numbers', () => {
    // test cases here
  });
});

To write individual test cases, use Mocha’s it function and place the tests inside a describe function. Notice that the first argument in the it function is a string describing what the test does. Below is a calculateTax function and its companion test (in separate files):

calculateTaxAmount(salePrice: number, taxRate: number) : number {
  return salePrice * (1 + taxRate)
}

describe('TaxCalculator', () =>
{
  describe('test calculateTaxAmount(salesPrice, taxRate)', () =>
  {
    it('should calculate the tax for an item', () =>
    {
      let taxCalculator = new TaxCalculator();
      expect(taxCalculator
      .calculateTaxAmount(25, .05))
      .to
      .equal(26.25);
    });
  });
});

Notice that the test is nested inside two describe functions. The outer is to describe all tests in this group and the inner describes the tests related to the specific function you’re testing.

Rider is great for building tests with test-first strategies in mind. Below is an example of creating the tests for TaxCalculator.add before TaxCalculator.add exists, then adding the code for TaxCalculator.add.

Write tests first then code

Run TypeScript Tests

While you can use the test runner, Rider automatically recognizes unit tests and places a Run icon next to each test as well as their groups.

Notice there’s an arrow for each describe function so you can run the tests at the level you wish. Rider has options to run tests with coverage as well as with profiling, to meet all your testing needs.

Running tests is super fun

Once you’ve completed testing, export the test results to an HTML, XML, or custom format. This is a great way to demonstrate your testing results to the boss.

Export test results

Summary

There is much more you can do with Mocha and Chai, or any TypeScript unit testing framework you use that isn’t demonstrated here. However, we wanted to show how Rider is an excellent tool for efficient TypeScript and JavaScript testing.

Download Rider and let us know what you think!

image description