Testing and Debugging in MERN Applications
Tags: webdev, testing, beginners, javascript
Published: 2023-05-12 08:04:41

**Testing and Debugging in MERN Applications**


In this article, Testing and Debugging in MERN Applications and the different techniques we can implement them are discussed. During the production of a project in an organization, there are various repetitive phases to ensure it performs efficiently in the absence of any bugs or anomalies. Also, we will discuss what technologies one must have under the sleeves to excel at testing and debugging.


**Writing Unit Tests**

You should follow the standard way of writing unit tests for modules and components present in your MERN application. The availability of numerous unit testing frameworks such as Mocha, Jest and Jasmine can be used to write unit tests.

Let us look at an example where components fetch data from an API, displays it and the unit test code verifies if the correct data is displayed on the user's end. We perform the unit test code below using Jest.

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

test('renders data correctly', () => {
  const data = { name: 'John', age: 30 };
  const { getByText } = render(<MyComponent data={data} />);
  const nameElement = getByText(/John/);
  const ageElement = getByText(/30/);
  expect(nameElement).toBeInTheDocument();
  expect(ageElement).toBeInTheDocument();
});
```

**Using a Debugger**

When facing issues with code, you can move to debuggers tools like Chrome DevTools, NodeJS Debugger or VSCode debugger that will help you know the issues in your code. Explore features like Browser Inspect, setting up breakpoints or examining the variables to utilise the debugging tools well.

Given below is the request timeout issue we have with our API that can be resolved using NodeJS debugger tool.

```
function getUsers(req, res) {
  // This API endpoint returns a list of users
  const users = [/* ... */];
  // Simulate a slow request that times out
  setTimeout(() => {
    res.json(users);
  }, 10000);
}

// Use the debugger to step through the code
debugger;
app.get('/users', getUsers);
```

**Checking Logs**

Logging is another way to find the issues in your code. Morgan and Winston are some of the important tools that are used to log information in your MERN application.

Below is one of the examples where we used Winston to log in order to get rid of the glitch where user session is expiring earlier than expected.

```
const winston = require('winston');

function handleUserSession(req, res) {
  const userId = req.session.userId;
  const sessionExpiresAt = req.session.expiresAt;
  const currentTime = new Date().getTime();
  if (currentTime > sessionExpiresAt) {
    // Session has expired
    winston.error(`User session expired for userId=${userId}`);
    req.session.destroy();
    res.sendStatus(401);
  } else {
    // Session is still valid
    res.sendStatus(200);
  }
}
```

**Error handling middleware**
ExpressJS is a framework that is credible for the usage of error-handling middleware in MERN applications. It catches and handles the exception in code, logs the error and returns the error messages back to the user.

In the following example, the API returns an error that does not gives a description, here the express middleware can be used as follow:

```
function handleError(err, req, res, next) {
  // Log the error
  winston.error(`Error: ${err.message}`);
  // Return an error message to the client
  res.status(500).json({ error: 'Internal server error' });
}

app.use(handleError);

```

**API Testing**

To test if your API endpoints are working correctly for hassle-free passage of data, tools like Postman and Insomnia can be used. 

For example, you have an API endpoint that fetches some data from the database, here Postman can be used to test the endpoint if it is returning the data correctly.

```
GET http://localhost:3000/users
```

**UI Testing**

To identify the issues persisting in the UI components, testing can be performed with the help of tools like Jest, Enzyme and Cypress. 

In the following example, we used Enzymen UI testing to test the component if it is being rendered properly using the keyword ‘expect’.

```
import React from 'react';
import { shallow } from 'enzyme';
import UserList from './UserList';

test('renders user list correctly', () => {
  const users = [{ name: 'John', age: 30 }, { name: 'Mary', age: 25 }];
  const wrapper = shallow(<UserList users={users} />);
  expect(wrapper.find('li')).toHaveLength(2);
  expect(wrapper.find('li').at(0).text()).toEqual('John (30 years old)');
  expect(wrapper.find('li').at(1).text()).toEqual('Mary (25 years old)');
});
```
**Miscellaneous Uses**

Among the methods discussed for Testing and Debugging of MERN applications, there are certainly more tools that we can follow to do the same such as:- 

Linting can be used to catch and fix syntax errors and related issues. ESLint is one of the primary examples to perform linting.

Git and similar version control software can be used for branching and tracking the changes to the code. It can be used to move back to the already existing or previous versions of the software.

Monitoring tools like New Relic, and App Dynamics can be utilized to detect issues or check if the application performance is up to the mark.

**Conclusion**

In this article, we studied what is testing and debugging in MERN applications and how we can perform them. We also discussed the methods we can perform them such as unit tests, using a debugger or logger or testing our API, UI and similar methods.