TypeScript Testing Tips - Mocking Functions With Jest

TypeScript Testing Tips - Mocking Functions With Jest

Tips for mocking functions using TypeScript and Jest. Jest was originally built for JavaScript. Jest is a popular testing framework that covers all aspects of testing including mocking, verifying expectations, parallel test execution and code coverage reports. It's also light on configuration so there's a lot to like.

Jest is a popular testing framework that covers all aspects of testing including mocking, verifying expectations, parallel test execution and code coverage reports. It's also light on configuration so there's a lot to like.

But the name: Jest, and in particular that J, betrays a potential weakness. It was originally built for JavaScript, and while they've added TypeScript support since version 24, some things still feel a bit clunky out of the box. Below we look at one such example and show how we make things a bit cleaner.

Mocking Simple Functions

Let's say the code your testing calls out to the following helper function in a file called Converters.ts:

export function sterlingToEuros(amountSterling: number): number {
  // Perform lookup, calculation or call to another service
  ...
  return amountEuros;
}
  • For unit testing, you'll need a MockedFunction for sterlingToEuros, which allows you to:Control how the function behaves during tests via methods like mockReturnValue and mockReturnValueOnce.
  • Verify how your code interacted with the mock using, for example, to verify expectations.

To create the MockedFunction you need to mock the module containing the function:

jest.mock("./path/to/file/Converters.ts");

Now, during test execution sterlingToEuros is a Jest MockedFunction, but TypeScript doesn't know this at compile-time, so you're not getting the benefits of static-typing during development.You can cast it to the correct type with:

const sterlingToEurosMock = sterlingToEuros as jest.MockedFunction<(amountSterling: number) => number>;

But this is a bit long-winded, error-prone, and could detract from what's important in the test. Bear in mind, also, that many functions will have a more complex signature perhaps having multiple parameters, custom types, generics or async, and so the above approach could get really cumbersome.TypeScript's type inference allows us to clean this up if we add the following helper:

export function mockFunction<T extends (...args: any[]) => any>(fn: T): jest.MockedFunction<T> {
  return fn as jest.MockedFunction<T>;
}

It probably makes sense to add this in a JestHelpers.ts file, and future posts will show other useful helper functions that could live alongside it.You can now use this helper in your tests as follows:

const sterlingToEurosMock = mockFunction(sterlingToEuros);

eliminating the need to include a lengthy function signature. Your mock will have the correct type and you can use it as expected:

it("should report value in Euros", () => {
  sterlingToEurosMock.mockReturnValue(50);
  expect(getCost()).toEqual(50);
  expect(sterlingToEurosMock).toHaveBeenCalledWith(45);
});

The compiler will ensure you don't make any type errors, for example:

// sterlingToEuros can only be set up to return type number
sterlingToEurosMock.mockReturnValue("50");                // Error
sterlingToEurosMock.mockReturnValue(null);                // Error
// sterlingToEuros can only be called with a single argument of type number
expect(sterlingToEurosMock).toHaveBeenCalledWith();       // Error
expect(sterlingToEurosMock).toHaveBeenCalledWith(12, 34); // Error 

testing typescript jest javascript developer

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Jest Tutorial for Beginners - JavaScript Testing with Jest Framework

In this Jest tutorial for beginners, you'll learn how to getting started with JavaScript unit testing with Jest framework. What means testing? How to test JavaScript code with Jest? Learn the basics of testing JavaScript with this Jest tutorial for beginners!

Asynchronous JavaScript Testing with Selenium and Jest

I will explain how to write test automation with Selenium using the Jest framework as Asynchronously in JavaScript. Selenium is the most used web application testing framework in the field of QA and especially in test automation projects. The Jest that I’m going to explain today is a testing framework that is maintained by Facebook that loves to use and known as well by many software developers who can write JavaScript.

Unit Testing With Jest in Javascript

I decided to spend today learning the ins and out of using Jest and creating test cases so that I may add unit tests to my projects.

Building A Test Runner in Jest - A How-To Guide

I use Jest nearly every day when working, and it's a fantastic tool. It lets me ship my code with confidence, knowing that I have produced something which works as intended.

Easy JavaScript unit tests in WordPress with Jest

Ensure the stability of the JavaScript code in your WordPress plugin by writing JavaScript unit tests using Jest. WordPress has a long record of unit testing its PHP code. However, writing JavaScript unit tests and integration tests for the code in themes and plugins doesn’t enjoy the same status. Let’s see how to test the JavaScript in our WordPress plugins and themes using Jest.