Test Driven Development with React
Published: 2023-02-06 06:00:29

React is a popular JavaScript library for building user interfaces, and using a test-driven development (TDD) approach can help ensure that your code is working correctly and catch bugs early in the development process. This article will show you how to implement TDD in a React app with three buttons: Add, Remove, and Reset.

First, let's create a simple React component to display a count and the three buttons.

```
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const handleAdd = () => {
    setCount(count + 1);
  };

  const handleRemove = () => {
    setCount(count - 1);
  };

  const handleReset = () => {
    setCount(0);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleAdd}>Add</button>
      <button onClick={handleRemove}>Remove</button>
      <button onClick={handleReset}>Reset</button>
    </div>
  );
}

export default Counter;

```

Next, let's write test scripts to verify that the buttons and count are functioning as expected. We'll use Jest as the testing framework.

```
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import Counter from './Counter';

describe('Counter', () => {
  it('displays the count', () => {
    const { getByText } = render(<Counter />);
    const countElement = getByText('Count: 0');
    expect(countElement).toBeInTheDocument();
  });

  it('increases the count when the Add button is clicked', () => {
    const { getByText } = render(<Counter />);
    const addButton = getByText('Add');
    fireEvent.click(addButton);
    const countElement = getByText('Count: 1');
    expect(countElement).toBeInTheDocument();
  });

  it('decreases the count when the Remove button is clicked', () => {
    const { getByText } = render(<Counter />);
    const removeButton = getByText('Remove');
    fireEvent.click(removeButton);
    const countElement = getByText('Count: -1');
    expect(countElement).toBeInTheDocument();
  });

  it('resets the count to 0 when the Reset button is clicked', () => {
    const { getByText } = render(<Counter />);
    const resetButton = getByText('Reset');
    fireEvent.click(resetButton);
    const countElement = getByText('Count: 0');
    expect(countElement).toBeInTheDocument();
  });

  it('does not go below 0 when the count is decremented', () => {
    const { getByText } = render(<Counter />);
    const removeButton = getByText('Remove');
    fireEvent.click(removeButton);
    let countElement = getByText('Count: -1');
    expect(countElement).toBeInTheDocument();
    fireEvent.click(removeButton);
countElement = getByText('Count: -2');
expect(countElement).toBeInTheDocument();
fireEvent.click(removeButton);
countElement = getByText('Count: -3');
expect(countElement).toBeInTheDocument();

const addButton = getByText('Add');
fireEvent.click(addButton);
countElement = getByText('Count: -2');
expect(countElement).toBeInTheDocument();
fireEvent.click(addButton);
countElement = getByText('Count: -1');
expect(countElement).toBeInTheDocument();
fireEvent.click(addButton);
countElement = getByText('Count: 0');
expect(countElement).toBeInTheDocument();




```