intermediate 16 min read

Testing with Jest

Write unit tests, integration tests, and mocks using the Jest testing framework.

Jest Testing Framework

// Install: npm install --save-dev jest supertest\n\n// math.js\nexport const add = (a, b) => a + b;\nexport const divide = (a, b) => {\n  if (b === 0) throw new Error('Cannot divide by zero');\n  return a / b;\n};\n\n// math.test.js\nimport { add, divide } from './math';\n\ndescribe('Math utilities', () => {\n  test('adds 1 + 2 equals 3', () => {\n    expect(add(1, 2)).toBe(3);\n  });\n\n  test('adds negative numbers', () => {\n    expect(add(-1, -2)).toBe(-3);\n  });\n\n  test('throws on division by zero', () => {\n    expect(() => divide(5, 0)).toThrow('Cannot divide by zero');\n  });\n});\n\n// Async testing\ntest('fetches user data', async () => {\n  const data = await fetchUser(1);\n  expect(data).toHaveProperty('id', 1);\n});\n\n// Mocking\njest.mock('./database');\nconst db = require('./database');\ndb.query.mockResolvedValue([{ id: 1, name: 'Alice' }]);

Integration Testing with Supertest

const request = require('supertest');\nconst app = require('../app');\n\ndescribe('GET /api/users', () => {\n  it('returns user list', async () => {\n    const res = await request(app)\n      .get('/api/users')\n      .expect(200);\n    \n    expect(res.body).toBeInstanceOf(Array);\n  });\n\n  it('requires authentication', async () => {\n    await request(app)\n      .get('/api/profile')\n      .expect(401);\n  });\n});

Examples

// user-service.test.js
const { getUser, createUser } = require('./user-service');
const db = require('./database');

jest.mock('./database');

describe('User Service', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  test('getUser returns user by ID', async () => {
    db.query.mockResolvedValue([{ id: 1, name: 'Alice', email: '[email protected]' }]);

    const user = await getUser(1);
    
    expect(user).toMatchObject({ id: 1, name: 'Alice' });
    expect(db.query).toHaveBeenCalledWith(
      'SELECT * FROM users WHERE id = $1',
      [1]
    );
  });

  test('createUser inserts and returns new user', async () => {
    db.query
      .mockResolvedValueOnce({ rows: [] }) // No duplicate
      .mockResolvedValueOnce({ rows: [{ id: 2, name: 'Bob' }] }); // Insert

    const user = await createUser({ name: 'Bob', email: '[email protected]' });
    
    expect(user).toHaveProperty('id');
    expect(db.query).toHaveBeenCalledTimes(2);
  });

  test('createUser throws on duplicate email', async () => {
    db.query.mockResolvedValue({ rows: [{ id: 1 }] }); // User exists

    await expect(
      createUser({ name: 'Bob', email: '[email protected]' })
    ).rejects.toThrow('Email already exists');
  });
});

console.log('Test file ready');

Your Notes

Sign in to take notes for this lesson.

Discussion

Sign in to join the discussion.

Flashcards

Sign in to create flashcards.