All skills
asyrafhussin avatar

/testing-best-practices

@575c801

Unit testing, integration testing, and test-driven development principles. Use when writing tests, reviewing test code, improving test coverage, or setting up testing strategy. Triggers on "write tests", "review tests", "testing best practices", or "TDD".

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/testing-best-practices

This session only. Nothing lands on disk.

rulesmock-realistic.md

≈1.1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Use Realistic Mock Behavior

Impact: MEDIUM (catches 30% more integration bugs by simulating real API behavior)

Mocks should behave like the real dependency — return realistic data structures, simulate error responses, and respect the contract of the thing they replace.

Incorrect

// ❌ Bad: mocks that always succeed with minimal data
const mockApi = {
  getUser: vi.fn().mockResolvedValue({ name: 'test' }),
  createOrder: vi.fn().mockResolvedValue(true),
  fetchProducts: vi.fn().mockResolvedValue([]),
};

describe('Dashboard', () => {
  test('loads user data', async () => {
    const dashboard = new DashboardService(mockApi);
    const data = await dashboard.load('user_1');

    // Mock returns { name: 'test' } — missing id, email, role, createdAt
    // Real API returns a full user object; code accessing user.role will crash in production
    expect(data.user.name).toBe('test');
  });

  test('creates an order', async () => {
    const dashboard = new DashboardService(mockApi);
    const result = await dashboard.placeOrder({ productId: 'p1', quantity: 2 });

    // Mock returns `true` — real API returns { orderId, status, estimatedDelivery }
    // No error path tested at all
    expect(result).toBe(true);
  });
});

Problems:

  • Incomplete mock responses hide runtime errors when real fields are accessed
  • Never testing error paths means error handling code is unverified
  • mockResolvedValue(true) doesn't match the real API contract
  • Tests pass in CI but the feature breaks in production

Correct

// ✅ Good: realistic mocks with MSW for API simulation
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';

// Realistic response shapes matching the actual API contract
const handlers = [
  http.get('/api/users/:id', ({ params }) => {
    if (params.id === 'not_found') {
      return HttpResponse.json(
        { error: 'User not found', code: 'USER_NOT_FOUND' },
        { status: 404 },
      );
    }

    return HttpResponse.json({
      id: params.id,
      name: 'Alice Johnson',
      email: 'alice@example.com',
      role: 'admin',
      createdAt: '2024-01-15T10:30:00Z',
    });
  }),

  http.post('/api/orders', async ({ request }) => {
    const body = (await request.json()) as Record<string, unknown>;

    if (!body.productId) {
      return HttpResponse.json(
        { error: 'Product ID is required', code: 'VALIDATION_ERROR' },
        { status: 400 },
      );
    }

    return HttpResponse.json(
      {
        orderId: 'order_789',
        status: 'confirmed',
        estimatedDelivery: '2024-02-01',
        items: [{ productId: body.productId, quantity: body.quantity }],
      },
      { status: 201 },
    );
  }),
];

const server = setupServer(...handlers);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

describe('DashboardService', () => {
  const service = new DashboardService();

  test('loads complete user profile', async () => {
    const data = await service.load('user_1');

    expect(data.user).toMatchObject({
      id: 'user_1',
      name: expect.any(String),
      email: expect.stringContaining('@'),
      role: expect.any(String),
    });
  });

  test('handles user not found gracefully', async () => {
    const data = await service.load('not_found');

    expect(data.user).toBeNull();
    expect(data.error).toBe('User not found');
  });

  test('creates order with full response data', async () => {
    const result = await service.placeOrder({ productId: 'p1', quantity: 2 });

    expect(result).toMatchObject({
      orderId: expect.stringMatching(/^order_/),
      status: 'confirmed',
      estimatedDelivery: expect.any(String),
    });
  });

  test('rejects order with missing product ID', async () => {
    await expect(
      service.placeOrder({ productId: '', quantity: 1 })
    ).rejects.toThrow('Product ID is required');
  });
});

Benefits:

  • MSW intercepts real fetch/axios calls — no manual mock wiring needed
  • Response shapes match the actual API contract, catching field-access bugs early
  • Both success and error paths are tested with realistic status codes
  • Tests run against the same HTTP layer used in production

Reference: Mock Service Worker

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides comprehensive guidelines and best practices for unit testing, integration testing, and Test-Driven Development (TDD). It consists entirely of documentation and illustrative code examples using industry-standard tools like Jest and Vitest. No security risks or malicious patterns were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    29 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 575c801. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 7 months ago
metadata
{
  "author": "agent-skills",
  "version": "2.0.0"
}

README badge

README badge for asyrafhussin/agent-skills/testing-best-practices