Get rid of the dependencies with ease

Importing libraries to extend software capabilities is a productive approach in development. As described in the DRY (Don’t Repeat Yourself) principle, it is not sensible to reinvent the wheels in most cases. Building application with libraries makes much sense. However, in TDD, testing your functions depending on third party libraries could be tricky if it lacks planning.
Let’s warm up by writing a simple Typescript function to hit an external REST service SpaceX-API and retrieve the response’s name attribute. We will leverage the popular Rest library ‘Axios’ and ride on the get() function to implement it. Sitting on a giant’s shoulder, isn’t it?

It’s time to roll your sleeves up. Are you ready?
Setup
If you are hungry for the source code, check out here.
In a brand new project, install dependencies for development.
$ yarn add -D typescript jest @types/jest ts-jest
Create Typescript config tsconfig.json
$ tsc --init
Create Jest config jest.config.js
$ yarn ts-jest config:init
Add roots property in jest.config.js.
roots: [ '<rootDir>/src' ],
Lastly, create an empty src folder under the project root directory.
Wanna know more about the setup? Head over to Jest with Typescript.
Scenario
We’re gonna write a module that uses Axios to make an HTTP Get request to free SpaceX-API.
Let’s hit the endpoint to see what the outcome will be.
GET https://api.spacexdata.com/v4/launches/latest
Our goal is to retrieve the name attribute under the root in the response. The name value is “Turksat 5A” when this post is written. This value changes when there is a new flight. It is a perfect example to demonstrate the unit test will be flaky if it relies on real endpoint. We will discuss about it very soon.
{ ... flight_number: 113, name: “Turksat 5A”, ... }
Simple enough?
Unit Test
We’ll get started with a test case under the ‘src’ folder. In the test, we will call a fetch() function that will be implemented very soon (line 3). The result will be tested against our expected ‘Turksat 5A’ (line 4).
import { fetch } from "./data";
it("returns name successfully", async () => {
const actual = await fetch();
expect(actual.data.name).toBe("Turksat 5A");
});
Next, we’ll implement our fetch() in data.ts and return an empty string.
export const fetch = async () => {
const result = '';
return result;
};
Compile the module, generate the build, and run the test.
$ tsc — outDir build && npx jest
It failed as expected.
➜ mock-library-jest-typescript git:(main) ✗ npx jest FAIL src/data.test.ts ✕ returns name successfully (4 ms)
● returns name successfully
expect(received).toBe(expected) // Object.is equality
Expected: "Turksat 5A" Received: {}
3 | it("returns name successfully", async () => { 4 | const actual = fetch(); > 5 | expect(actual).toBe("Turksat 5A"); | ^ 6 | }); 7 |
at src/data.test.ts:5:18 at step (src/data.test.ts:33:23) at Object.next (src/data.test.ts:14:53) at src/data.test.ts:8:71 at Object.<anonymous>.__awaiter (src/data.test.ts:4:12) at Object.<anonymous> (src/data.test.ts:3:33)
Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total Snapshots: 0 total Time: 0.551 s, estimated 2 s Ran all test suites.
Don’t panic.
Let’s update data.ts with real functionality.
Implementation
Install Axios.
$ yarn add axios
Update fetch() to return a promise of Axios response.
import axios from "axios";
export const fetch = async () =>
await axios.get("https://api.spacexdata.com/v4/launches/latest");
Re-run the test and it passes. Hurray! 🚀
➜ mock-library-jest-typescript git:(main) ✗ npx jest PASS src/data.test.ts ✓ returns name successfully (205 ms)
Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 2.021 s Ran all test suites.
Why mocking?
The nightly build is so reassuring until the SpaceX-API is down for maintenance on the other night. You were awake by a Slack notification warning of a failure in the CI pipeline.

Imagine you are in an incredible tech team delivering with CI/CD timely. The data module is part of the data acquisition services in the company. The unit test we have just written depends on the external API. In other words, the test results are tightly coupled with the availability of the SpaceX-API. It is crucial to be notified when the endpoint was not working. However, it is not the concern of the unit test. Our unit test aims to ensure the fetch() works properly against the contract of the endpoint. The test verifies the implementation can handle different scenarios such as bad requests, successful calls, service unavailable, etc., that are defined in the contract.
To avoid an unnecessary failing in the tests, we’re gonna get rid of the dependencies by mocking.
Jest mock function
Jest provides a mock function for replacing a Node module during the test. In the test file data.spec.ts, import the Axios library and instruct Jest to mock it up.
import axios, { AxiosResponse } from "axios";
jest.mock("axios");
Create an object of type of mocked Axios.
const mockedAxios = axios as jest.Mocked<typeof axios>;
Now you have full control of the mocked Axios. Of course, we want to make our desired output for the get function. Here we go.
const mockedResponse: AxiosResponse = {
data: {
name: "Henry",
},
status: 200,
statusText: "OK",
headers: {},
config: {},
};
It’s time to wire up the get function of our mocked Axios and our desired output. As the get function is asynchronous, we use mockResolvedValue for a success case.
mockedAxios.get.mockResolvedValue(mockedResponse);
In our assertion, we first make sure the mocked axios.get() has not been called before we trigger the fetch() function.
After we call the fetch(), we presume the mocked axios.get() in invoked with the toHaveBeenCalled() function.
expect(axios.get).not.toHaveBeenCalled();
const actual = await fetch();
expect(axios.get).toHaveBeenCalled();
Finally, we assert the response object contains our mocked value.
expect(actual.data.name).toEqual(“Henry”);
Run our test again.
It passes! Meaning the test satisfied the contract.
Here is the key takeaway of this post.
- Remove the third parties dependencies from the unit tests.
- By mocking functions with Jest, you can test your implementation based on contract rather than the real services.
The complete source code can be found here.
Happy coding and sleep tight!

If you like testing with Jest in Typescript, you might be interested in the other two posts in the Jest series. Cheers.