jest-testing

pluginagentmarketplace's avatarfrom pluginagentmarketplace

Test Node.js applications with Jest including unit tests, integration tests, mocking, code coverage, and CI/CD integration

⭐1stars🔀0forks📁View on GitHub🕐Updated Dec 31, 2025

When & Why to Use This Skill

This Claude skill provides a comprehensive toolkit for mastering Node.js application testing using Jest. It covers the entire testing lifecycle, from basic unit tests and complex integration testing to advanced mocking patterns and automated code coverage. Designed to enhance software reliability, it helps developers implement the AAA (Arrange, Act, Assert) pattern and integrate seamless testing workflows into CI/CD pipelines.

Use Cases

  • Unit Testing: Validating isolated business logic and utility functions using Jest's extensive library of matchers.
  • API Testing with Supertest: Performing end-to-end verification of RESTful API endpoints, including status codes, headers, and payload validation.
  • Mocking Dependencies: Using jest.mock and spies to isolate code from external services, databases, or third-party APIs for predictable testing.
  • Code Coverage Optimization: Generating and analyzing coverage reports to identify untested code paths and maintain high-quality standards.
  • CI/CD Pipeline Integration: Automating test suites within GitHub Actions or other platforms to ensure code stability before deployment.
namejest-testing
descriptionTest Node.js applications with Jest including unit tests, integration tests, mocking, code coverage, and CI/CD integration
sasmp_version"1.3.0"
bonded_agent01-nodejs-fundamentals
bond_typePRIMARY_BOND

Jest Testing Skill

Master testing Node.js applications with Jest - the delightful JavaScript testing framework.

Quick Start

Test in 3 steps:

  1. Install - npm install --save-dev jest supertest
  2. Write Test - Create *.test.js files
  3. Run - npm test

Core Concepts

Basic Test Structure

// sum.test.js
const sum = require('./sum');

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

  test('adds negative numbers', () => {
    expect(sum(-1, -2)).toBe(-3);
  });
});

Jest Configuration

// package.json
{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage"
  },
  "jest": {
    "testEnvironment": "node",
    "coverageThreshold": {
      "global": {
        "branches": 80,
        "functions": 80,
        "lines": 80
      }
    }
  }
}

Unit Testing

// userService.test.js
const UserService = require('./userService');
const User = require('./models/User');

jest.mock('./models/User');

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

  describe('createUser', () => {
    it('should create user successfully', async () => {
      const userData = {
        name: 'John',
        email: 'john@example.com'
      };

      User.create.mockResolvedValue({ id: 1, ...userData });

      const result = await UserService.createUser(userData);

      expect(User.create).toHaveBeenCalledWith(userData);
      expect(result.id).toBe(1);
    });

    it('should throw error for duplicate email', async () => {
      User.create.mockRejectedValue(new Error('Email exists'));

      await expect(UserService.createUser({}))
        .rejects
        .toThrow('Email exists');
    });
  });
});

Learning Path

Beginner (1-2 weeks)

  • ✅ Setup Jest and write basic tests
  • ✅ Understand test structure (describe/it/expect)
  • ✅ Learn matchers (toBe, toEqual, etc.)
  • ✅ Test synchronous functions

Intermediate (3-4 weeks)

  • ✅ Test async functions
  • ✅ Mock modules and functions
  • ✅ API testing with Supertest
  • ✅ Code coverage reports

Advanced (5-6 weeks)

  • ✅ Integration testing
  • ✅ Test database operations
  • ✅ CI/CD integration
  • ✅ Performance testing

API Testing with Supertest

const request = require('supertest');
const app = require('./app');

describe('User API', () => {
  describe('POST /api/users', () => {
    it('should create new user', async () => {
      const userData = {
        name: 'John',
        email: 'john@example.com',
        password: 'password123'
      };

      const response = await request(app)
        .post('/api/users')
        .send(userData)
        .expect('Content-Type', /json/)
        .expect(201);

      expect(response.body).toHaveProperty('id');
      expect(response.body.email).toBe(userData.email);
    });

    it('should return 400 for invalid email', async () => {
      const response = await request(app)
        .post('/api/users')
        .send({ email: 'invalid' })
        .expect(400);

      expect(response.body).toHaveProperty('error');
    });
  });

  describe('GET /api/users/:id', () => {
    it('should return user by id', async () => {
      const response = await request(app)
        .get('/api/users/123')
        .expect(200);

      expect(response.body.id).toBe('123');
    });

    it('should return 404 for non-existent user', async () => {
      await request(app)
        .get('/api/users/999')
        .expect(404);
    });
  });
});

Mocking Patterns

// Mock entire module
jest.mock('axios');
const axios = require('axios');

test('fetches data from API', async () => {
  axios.get.mockResolvedValue({ data: { id: 1 } });

  const result = await fetchUser(1);

  expect(axios.get).toHaveBeenCalledWith('/api/users/1');
  expect(result.id).toBe(1);
});

// Spy on function
test('calls callback', () => {
  const callback = jest.fn();

  processData('test', callback);

  expect(callback).toHaveBeenCalledWith('test');
  expect(callback).toHaveBeenCalledTimes(1);
});

// Mock timers
jest.useFakeTimers();

test('delays execution', () => {
  const callback = jest.fn();

  setTimeout(callback, 1000);
  jest.advanceTimersByTime(1000);

  expect(callback).toHaveBeenCalled();
});

Test Lifecycle Hooks

describe('User Tests', () => {
  beforeAll(async () => {
    // Setup test database
    await connectTestDB();
  });

  afterAll(async () => {
    // Cleanup
    await disconnectTestDB();
  });

  beforeEach(async () => {
    // Clear data before each test
    await User.deleteMany({});
  });

  afterEach(() => {
    // Cleanup after each test
    jest.clearAllMocks();
  });

  test('...', () => {});
});

Jest Matchers

// Equality
expect(value).toBe(expected)        // Strict equality (===)
expect(value).toEqual(expected)     // Deep equality
expect(value).not.toBe(expected)    // Negation

// Truthiness
expect(value).toBeDefined()
expect(value).toBeNull()
expect(value).toBeTruthy()
expect(value).toBeFalsy()

// Numbers
expect(value).toBeGreaterThan(3)
expect(value).toBeGreaterThanOrEqual(3)
expect(value).toBeLessThan(5)
expect(value).toBeCloseTo(0.3)      // Floating point

// Strings
expect(string).toMatch(/pattern/)
expect(string).toContain('substring')

// Arrays
expect(array).toContain(item)
expect(array).toHaveLength(3)

// Objects
expect(obj).toHaveProperty('key')
expect(obj).toMatchObject({ key: 'value' })

// Exceptions
expect(() => fn()).toThrow()
expect(() => fn()).toThrow('error message')

// Async
await expect(promise).resolves.toBe(value)
await expect(promise).rejects.toThrow()

Code Coverage

# Run with coverage
npm test -- --coverage

# Coverage report shows:
# - Statements: % of code executed
# - Branches: % of if/else paths
# - Functions: % of functions called
# - Lines: % of lines executed

Testing Best Practices

  • ✅ AAA pattern: Arrange, Act, Assert
  • ✅ One assertion per test (ideally)
  • ✅ Descriptive test names
  • ✅ Test edge cases
  • ✅ Mock external dependencies
  • ✅ Clean up after tests
  • ✅ Avoid test interdependence
  • ✅ Aim for 80%+ coverage

CI/CD Integration

# .github/workflows/test.yml
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm ci
      - run: npm test -- --coverage
      - uses: codecov/codecov-action@v3

When to Use

Use Jest testing when:

  • Building Node.js applications
  • Need comprehensive test coverage
  • Want fast, parallel test execution
  • Require mocking and snapshot testing
  • Implementing CI/CD pipelines
  • Express REST API (test API endpoints)
  • Async Programming (test async code)
  • Database Integration (test DB operations)
  • JWT Authentication (test auth flows)

Resources