typescriptadvanced

Testing Server Components

Test Next.js server components and server actions using testing-library and mocks.

typescript
// __tests__/page.test.tsx
import { render, screen } from '@testing-library/react';
import HomePage from '@/app/page';

// Mock fetch for server components
global.fetch = jest.fn(() =>
  Promise.resolve({
    ok: true,
    json: () => Promise.resolve([
      { id: '1', title: 'Test Post', excerpt: 'Test excerpt' },
    ]),
  })
) as jest.Mock;

describe('HomePage', () => {
  it('renders the page title', async () => {
    const page = await HomePage();
    render(page);
    expect(screen.getByRole('heading', { level: 1 })).toBeInTheDocument();
  });
});

// Testing Server Actions
// __tests__/actions.test.ts
import { createPost } from '@/app/actions';

jest.mock('next/cache', () => ({
  revalidatePath: jest.fn(),
  revalidateTag: jest.fn(),
}));

jest.mock('next/navigation', () => ({
  redirect: jest.fn(),
}));

describe('createPost action', () => {
  it('creates a post with valid data', async () => {
    const formData = new FormData();
    formData.set('title', 'Test Post');
    formData.set('content', 'Test content here');

    const result = await createPost({ success: false }, formData);
    expect(result.success).toBe(true);
  });

  it('returns errors for invalid data', async () => {
    const formData = new FormData();
    formData.set('title', ''); // Empty title

    const result = await createPost({ success: false }, formData);
    expect(result.success).toBe(false);
    expect(result.errors).toBeDefined();
  });
});

// Testing Route Handlers
// __tests__/api.test.ts
import { GET, POST } from '@/app/api/posts/route';

describe('POST /api/posts', () => {
  it('creates a new post', async () => {
    const request = new Request('http://localhost/api/posts', {
      method: 'POST',
      body: JSON.stringify({ title: 'Test', content: 'Body' }),
    });
    const response = await POST(request);
    expect(response.status).toBe(201);
  });
});

Use Cases

  • unit testing
  • integration testing
  • CI/CD pipelines

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.