Jest - Step by Step (Bite-size Article)
Tags: jest, testing, beginners, react
Published: 2024-02-23 14:40:45

#Introduction

**Jest** is a JavaScript <u>testing framework</u> developed by Facebook (Currently Meta Platforms, inc.). It is primarily used for testing web applications created with JavaScript frameworks such as React, Vue.js, and Angular, but it is also widely used for testing JavaScript code, including Node.js.

I've had some opportunities to use Jest recently, and although I learned about it a while back at school, I haven't had many chances to use it since then. Therefore, I've decided to write this article. Since I'm not very familiar with the basics of Jest myself, this will also serve as a way for me to organize the fundamental aspects of Jest. I hope that by sharing my findings, it might also serve as a reference for someone new to Jest.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mhnp6rkxfojra7fn344g.png)



#Jest Installation and Settings
In this article, we'll create a very simple test component in React and try testing both a <u>success and a failure scenarios</u> to see those results. Especially for beginners, intentionally creating and testing failure scenarios might deepen your understanding.

We'll start by creating a project file with `create-react-app`.

```shell
npx create-react-app jest-test
```

Installing React project in this way includes a basic test environment as default, so you can begin testing immediately without any additional settings. However, if you need to install and configure Jest manually, you would need install some library and add script to package.json like following :

```shell
#In case you use Jest and testing library, run this
npm install --save-dev jest @testing-library/react @testing-library/jest-dom
```

If your package.json has no test script, add the test script:

```json
{
  "scripts": {
    "test": "jest",
  }
}
```

Though this may not be necessary if you're starting with create-react-app, it might be useful for those who need it.
* Note that the details may vary depending on your environment.

#Create Simple Test files
Here is an example of testing a simple text input form component. This component allows the user to enter text and has the ability to save the input values.

```js
// TextInput.js
import React, { useState } from 'react';

function TextInput({ onSave }) {
  const [inputValue, setInputValue] = useState('');

  const handleChange = (event) => {
    setInputValue(event.target.value);
  };

  const handleSubmit = () => {
    onSave(inputValue);
    setInputValue(''); // after set input, clear input field
  };

  return (
    <div>
      <input
        type="text"
        value={inputValue}
        onChange={handleChange}
        placeholder="Enter text"
      />
      <button onClick={handleSubmit}>Save</button>
    </div>
  );
}

export default TextInput;
```

And following is test file.

```js
// TextInput.test.js
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import TextInput from './TextInput';

test('renders TextInput with placeholder', () => {
  render(<TextInput onSave={() => {}} />);
  expect(screen.getByPlaceholderText('Enter text')).toBeInTheDocument();
});

test('allows users to input text and save', () => {
  const mockOnSave = jest.fn();
  render(<TextInput onSave={mockOnSave} />);

  // user input text
  fireEvent.change(screen.getByPlaceholderText('Enter text'), {
    target: { value: 'New text' },
  });

  // click save button
  fireEvent.click(screen.getByText('Save'));

  // Confirmation that onSave was called with the correct value
  expect(mockOnSave).toHaveBeenCalledWith('New text');

  // Check text fields are cleared
  expect(screen.getByPlaceholderText('Enter text').value).toBe('');
});

```

This test suite tests the following functions:

1. 
Rendering and Placeholder Verification: Verify that the TextInput component is rendered and displays the specified placeholder text.

2. 
Handling user input and saving: Verify that the user can enter text, that the input is saved by clicking the Save button, and that the state of the component is properly updated (in this case, the input field is cleared).

Through these tests, verify that the TextInput component functions properly and responds to expected user interactions.

##Tip: FireEvent
**fireEvent** is a utility included in `@testing-library/react`, a testing library for React. It allows you to simulate DOM events to test how components in test respond to user actions, such as clicks and input.

Once you have completed the files up to this point, please try running `npm test` in the console. If you have followed the content correctly until so far, you should not encounter any errors, and the console should display results indicating that the test suite has passed successfully.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6bwg402x3levai9a9d35.png)



#Failure Scenarios
Next, let's intentionally write some incorrect code to see how the test fails.

##1. Incorrect Placeholder Text:

We will deliberately change the placeholder value in the TextInput.js component to an incorrect one.

```jsx
// Modification in <input> of TextInput.js
<input
  type="text"
  value={inputValue}
  onChange={handleChange}
  placeholder="Wrong placeholder" // Change: from the correct placeholder to an incorrect one
/>
```

This change will cause the placeholder test to fail. Let's see the where the place is in test file.

```jsx
// TextInput.test.js
test('renders TextInput with placeholder', () => {
  render(<TextInput onSave={() => {}} />);
  expect(screen.getByPlaceholderText('Enter text')).toBeInTheDocument(); // fails at this line
});
```

This happens because the test file is checking for a placeholder value of “Enter Text”.

---

Next, Let me introduce another example of failure.

##2. Input Field Does Not Clear After Text Entry:

In the TextInput.js component, we will modify the code so that the input field is not cleared after saving the input.
```jsx
// Modification in the handleSubmit function of TextInput.js
const handleSubmit = () => {
  onSave(inputValue);
  // setInputValue(''); // Commented out to do not clear the input
};

```

This change will cause the test that verifies the input field is cleared to fail.


```jsx
// TextInput.test.js
test('allows users to input text and save', () => {
  const mockOnSave = jest.fn();
  render(<TextInput onSave={mockOnSave} />);

 // User enters text
  fireEvent.change(screen.getByPlaceholderText('Enter text'), {
    target: { value: 'New text' },
  });

  // Click the save button
  fireEvent.click(screen.getByText('Save'));

  // Verify the text field is cleared (this verification will fail)
  expect(screen.getByPlaceholderText('Enter text').value).toBe(''); // Fails at this line
});
```


#Conclusion

In this article, I explained the basics of Jest, including practical examples. I omitted detailed explanations this time, so if you want to delve deeper, please search on Google or check the official documentation.

In addition to what I’ve introduced here, trying to create your own tests and altering the corresponding code to see how they interact may deepen your understanding even further.

Thank you for reading, happy coding!