Dev Conventions
  • Dev Conventions
  • Git
    • Branch Flow
    • Conventional Commits
    • Pull requests template
    • Before making the PRs in typescript, keep in mind
  • Typescript
    • Introduction
    • Good practices
    • Solid
    • Using pnpm for Package Management
    • NestJs
    • NextJs
    • React
    • NestJs Testing
    • React Testing
    • Npm Registry
  • PYTHON
    • Introduction
    • Good practices
    • Testing
    • Naming Convention
  • DevOps
    • Introduction
    • Github Actions
    • Creating a Github Actions Workflow
  • Agile
    • Story Points
Powered by GitBook
On this page
  • Testing in React and Next.js with Jest and React Testing Library
  • Setting Up the Testing Environment
  • Writing Tests
  • Conclusion
  1. Typescript

React Testing

Testing in React and Next.js with Jest and React Testing Library

Testing is a critical aspect of software development, ensuring that your application behaves as expected and remains robust over time. This documentation will guide you through setting up and writing tests for your React and Next.js application using Jest and React Testing Library.

Setting Up the Testing Environment

Install Jest and React Testing Library

First, you need to install Jest and React Testing Library along with their dependencies:

pnpm add -D jest @testing-library/react @testing-library/jest-dom @testing-library/user-event @types/jest ts-jest

Configure Jest

Create a jest.config.js file in the root of your project with the following content:

module.exports = {
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
  transform: {
    '^.+\\.(ts|tsx)$': 'ts-jest',
  },
  testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
  collectCoverageFrom: [
    'src/**/*.{ts,tsx}',
    '!src/**/*.d.ts',
  ],
};

Setup Testing Library

Create a jest.setup.js file in the root of your project to configure React Testing Library and extend Jest with additional matchers:

import '@testing-library/jest-dom/extend-expect';

Writing Tests

Unit Testing React Components

Unit tests focus on testing individual components in isolation to ensure they behave as expected.

Example Component

Consider a simple Button component:

// src/components/Button.tsx
import React from 'react';

interface ButtonProps {
  label: string;
  onClick: () => void;
}

const Button: React.FC<ButtonProps> = ({ label, onClick }) => {
  return <button onClick={onClick}>{label}</button>;
};

export default Button;

Test File for Button Component

Create a test file named Button.test.tsx:

// src/components/Button.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import Button from './Button';

describe('Button', () => {
  it('renders the button with the correct label', () => {
    render(<Button label="Click Me" onClick={() => {}} />);
    expect(screen.getByText('Click Me')).toBeInTheDocument();
  });

  it('calls the onClick handler when clicked', () => {
    const handleClick = jest.fn();
    render(<Button label="Click Me" onClick={handleClick} />);
    fireEvent.click(screen.getByText('Click Me'));
    expect(handleClick).toHaveBeenCalledTimes(1);
  });
});

Integration Testing

Integration tests ensure that different parts of the application work together correctly.

Example Page Component

Consider a Home page that uses the Button component:

// src/pages/index.tsx
import React from 'react';
import Button from '../components/Button';

const Home: React.FC = () => {
  const handleClick = () => {
    console.log('Button clicked');
  };

  return (
    <div>
      <h1>Welcome to Next.js!</h1>
      <Button label="Click Me" onClick={handleClick} />
    </div>
  );
};

export default Home;

Test File for Home Page

Create a test file named index.test.tsx:

// src/pages/index.test.tsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import Home from './index';

describe('Home Page', () => {
  it('renders the heading', () => {
    render(<Home />);
    expect(screen.getByText('Welcome to Next.js!')).toBeInTheDocument();
  });

  it('renders the button', () => {
    render(<Home />);
    expect(screen.getByText('Click Me')).toBeInTheDocument();
  });
});

Mocking Next.js Data Fetching Methods

Next.js provides several data fetching methods, such as getStaticProps and getServerSideProps. You can mock these methods to test your pages.

Example Page with getStaticProps

// src/pages/about.tsx
import React from 'react';

interface AboutProps {
  data: string;
}

const About: React.FC<AboutProps> = ({ data }) => {
  return <div>{data}</div>;
};

export const getStaticProps = async () => {
  return {
    props: {
      data: 'Hello from getStaticProps',
    },
  };
};

export default About;

Test File for About Page

Create a test file named about.test.tsx:

// src/pages/about.test.tsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import About, { getStaticProps } from './about';

describe('About Page', () => {
  it('renders the data from getStaticProps', async () => {
    const { props } = await getStaticProps();
    render(<About {...props} />);
    expect(screen.getByText('Hello from getStaticProps')).toBeInTheDocument();
  });
});

End-to-End Testing with Cypress

For E2E testing, you can use Cypress, a powerful testing framework for web applications.

Install Cypress

pnpm add -D cypress

Configure Cypress

Add a cypress.json file in the root of your project:

{
  "baseUrl": "http://localhost:3000",
  "integrationFolder": "cypress/integration",
  "pluginsFile": "cypress/plugins/index.js",
  "supportFile": "cypress/support/index.js"
}

Create a Sample E2E Test

Create a test file named home.spec.js in the cypress/integration folder:

// cypress/integration/home.spec.js
describe('Home Page', () => {
  it('should display the welcome message', () => {
    cy.visit('/');
    cy.contains('Welcome to Next.js!').should('be.visible');
  });

  it('should click the button', () => {
    cy.visit('/');
    cy.contains('Click Me').click();
    // Verify the button click, e.g., by checking console output or state changes
  });
});

Running Cypress Tests

To run Cypress tests, add the following script to your package.json:

"scripts": {
  "cypress:open": "cypress open"
}

Then run the script:

pnpm cypress:open

This will open the Cypress test runner, allowing you to run your E2E tests interactively.

Conclusion

By setting up Jest and React Testing Library for your React and Next.js project, you can write comprehensive tests that ensure the correctness of your application at different levels. Unit tests validate individual components, integration tests check the interaction between components, and E2E tests verify the application's behavior as a whole. Following these practices will help you maintain a robust and reliable codebase.

PreviousNestJs TestingNextNpm Registry

Last updated 11 months ago