Jiaxi Liu (Jesse)

Master’s Graduate

Software Engineer | Scalable APIs · Web Scraping · Data Integration · Code Quality & Refactoring

Back to Blog

Jest and Supertest Review: Unit Tests, Mocks, Async Assertions, and API Integration Tests

Jest is useful for functions, service layers, React components, and async logic. Supertest is focused on HTTP API testing.

Jest Assertions

Common assertions:

expect(value).toBe(5);
expect(obj).toEqual({ id: 1 });
expect(value).toBeTruthy();
expect(arr).toContain("x");
expect(fn).toThrow(/error/);

For floating-point values, avoid direct equality.

expect(0.1 + 0.2).toBeCloseTo(0.3);

Unit Tests

Business function:

export function applyDiscount(price: number, discount: number) {
  if (discount < 0 || discount > 1) return price;
  return price * (1 - discount);
}

Tests:

test("calculates discount", () => {
  expect(applyDiscount(100, 0.2)).toBe(80);
});
 
test("returns original price for invalid discount", () => {
  expect(applyDiscount(100, 1.5)).toBe(100);
});

Mocking External Requests

Mocking isolates the current logic from external systems.

jest.mock("axios");
const mockedAxios = axios as jest.Mocked<typeof axios>;
 
mockedAxios.get.mockResolvedValueOnce({
  data: { id: 1, name: "Jesse" },
});
 
await expect(getUser(1)).resolves.toEqual({ id: 1, name: "Jesse" });
expect(mockedAxios.get).toHaveBeenCalledWith("/users/1");

Common mock targets:

  • Network requests
  • Database repositories
  • Time
  • Randomness
  • Third-party services

Async Tests

await expect(fetchUser()).resolves.toMatchObject({ id: 1 });
await expect(fetchUser()).rejects.toThrow();

Always return or await Promises in async tests.

API Testing with Supertest

Supertest can test Express, Next, or Nest APIs without binding a real port.

const res = await request(app)
  .get("/user/1")
  .query({ detail: "full" })
  .set("Authorization", "Bearer test123");
 
expect(res.statusCode).toBe(200);
expect(res.body).toHaveProperty("id", "1");

POST JSON:

await request(app)
  .post("/login")
  .send({ username: "jesse", password: "123456" })
  .expect(200);

API tests should check status codes, response shape, error branches, permissions, and boundary inputs.