TypeScript Testing (e.g., Jest, Mocha)

Testing is an essential part of software development, ensuring that your code works as expected and helping to prevent future regressions. TypeScript's strong typing system can catch many errors at compile time, but runtime testing is still necessary to verify logic and behavior. In this chapter, we will explore testing in TypeScript using popular frameworks like Jest and Mocha. We will cover everything from setup and basic tests to advanced testing strategies, ensuring you have a comprehensive understanding of how to effectively test your TypeScript code.

Getting Started with Jest

Introduction to Jest

Jest is a popular JavaScript testing framework developed by Facebook. It provides an out-of-the-box testing experience with features like zero configuration, fast iteration speed, and built-in mocking.

Setting Up Jest in a TypeScript Project

To set up Jest for a TypeScript project, follow these steps

				
					npm install --save-dev jest ts-jest @types/jest

				
			

Create a jest.config.js file in the root of your project:

				
					module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
};

				
			

Explanation:

  • ts-jest is a TypeScript preprocessor for Jest, enabling you to write your tests in TypeScript.
  • testEnvironment specifies the environment in which the tests will run.
  • testMatch defines the glob patterns Jest uses to detect test files.

Writing Basic Tests with Jest

Create a simple function to test:

				
					// src/math.ts
export function add(a: number, b: number): number {
  return a + b;
}

				
			

Create a test file:

				
					// __tests__/math.test.ts
import { add } from '../src/math';

test('adds 1 + 2 to equal 3', () => {
  expect(add(1, 2)).toBe(3);
});

				
			

Explanation:

  • test is a Jest function used to define a test case.
  • expect is an assertion function used to test values.

Output:

				
					PASS  __tests__/math.test.ts
  ✓ adds 1 + 2 to equal 3 (3ms)

				
			

Running Tests

Add a script to your package.json to run Jest:

				
					"scripts": {
  "test": "jest"
}

				
			

Run the tests using:

				
					npm test

				
			

Advanced Jest Features

Testing Asynchronous Code

Jest provides utilities to test asynchronous functions, including callbacks, promises, and async/await.

				
					// src/user.ts
export async function fetchUser(id: number): Promise<{ id: number, name: string }> {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ id, name: 'John Doe' });
    }, 1000);
  });
}

				
			
				
					// __tests__/user.test.ts
import { fetchUser } from '../src/user';

test('fetches user by ID', async () => {
  const user = await fetchUser(1);
  expect(user).toEqual({ id: 1, name: 'John Doe' });
});

				
			

Explanation:

  • async and await are used to handle asynchronous code.
  • toEqual checks for deep equality.

Output:

				
					PASS  __tests__/user.test.ts
  ✓ fetches user by ID (1003ms)

				
			

Mocking Dependencies

Jest’s mocking capabilities allow you to replace dependencies with mock implementations.

				
					// src/api.ts
export async function getData(): Promise<string> {
  // Simulate an API call
  return 'real data';
}

				
			
				
					// src/service.ts
import { getData } from './api';

export async function fetchData(): Promise<string> {
  return await getData();
}

				
			
				
					// __tests__/service.test.ts
import { fetchData } from '../src/service';
import * as api from '../src/api';

jest.mock('../src/api');

test('fetches mocked data', async () => {
  jest.spyOn(api, 'getData').mockResolvedValue('mocked data');
  const data = await fetchData();
  expect(data).toBe('mocked data');
});

				
			

Explanation:

  • jest.mock is used to mock the entire module.
  • jest.spyOn creates a mock function for a specific method.

Output:

				
					PASS  __tests__/service.test.ts
  ✓ fetches mocked data (3ms)

				
			

Getting Started with Mocha and Chai

  1. Introduction to Mocha and Chai

    Mocha is a flexible JavaScript testing framework for Node.js, and Chai is an assertion library that works well with Mocha.

  2. Setting Up Mocha and Chai in a TypeScript Project

    Install Mocha, Chai, and the necessary TypeScript dependencies:

				
					npm install --save-dev mocha chai ts-node @types/mocha @types/chai

				
			

Create a mocha.opts file in the root of your project:

				
					--require ts-node/register
--recursive

				
			

Explanation:

  • ts-node/register allows Mocha to run TypeScript files.
  • --recursive tells Mocha to include subdirectories.

Writing Basic Tests with Mocha and Chai

Create a simple function to test:

				
					// src/math.ts
export function multiply(a: number, b: number): number {
  return a * b;
}

				
			

Create a test file:

				
					// test/math.test.ts
import { expect } from 'chai';
import { multiply } from '../src/math';

describe('multiply', () => {
  it('should multiply 2 and 3 to get 6', () => {
    expect(multiply(2, 3)).to.equal(6);
  });
});

				
			

Explanation:

  • describe groups related tests.
  • it defines a single test case.
  • expect is used for assertions.

Output:

				
					multiply
  ✓ should multiply 2 and 3 to get 6

				
			

Running Tests

Add a script to your package.json to run Mocha:

				
					"scripts": {
  "test": "mocha 'test/**/*.ts'"
}

				
			

Run the tests using:

				
					npm test

				
			

Testing Best Practices

Writing Clear and Concise Tests

Ensure your test cases are easy to understand and maintain.

  • Use descriptive names for your tests.
  • Keep tests small and focused on a single piece of functionality.

Isolating Tests

Each test should be independent and not rely on the state left by previous tests.

  • Use setup and teardown hooks to prepare and clean up the environment.
				
					import { beforeEach, afterEach } from 'mocha';

describe('Test Suite', () => {
  beforeEach(() => {
    // Setup code
  });

  afterEach(() => {
    // Teardown code
  });

  it('should do something', () => {
    // Test code
  });
});

				
			

Mocking and Stubbing

Use mocks and stubs to isolate the unit of code being tested from its dependencies.

  • Jest and Sinon are great tools for this purpose.
				
					import sinon from 'sinon';

describe('fetchData', () => {
  it('should call getData once', async () => {
    const getDataStub = sinon.stub(api, 'getData').resolves('mocked data');
    await fetchData();
    expect(getDataStub.calledOnce).to.be.true;
    getDataStub.restore();
  });
});

				
			

Testing is an integral part of the development process, and mastering it ensures the reliability and robustness of your code. By leveraging frameworks like Jest and Mocha, you can write efficient and effective tests for your TypeScript projects. This chapter has covered the basics to advanced concepts of testing with Jest and Mocha, along with practical examples and best practices. Happy coding !❤️

Table of Contents

Contact here

Copyright © 2025 Diginode

Made with ❤️ in India