# Jest

### How to use

Here we use [Jest](https://jestjs.io/docs/getting-started) alongside with [React Testing Library](https://testing-library.com/docs/), [Test Renderer](https://reactjs.org/docs/test-renderer.html), and [Redux Mock Store](https://github.com/reduxjs/redux-mock-store).

### Snapshot Testing Example

Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly.

```jsx
import React from 'react';
import renderer from 'react-test-renderer';
import Link from '../Link.react';

it('renders correctly', () => {
  const tree = renderer
    .create(<Link page="http://www.facebook.com">Facebook</Link>)
    .toJSON();
  expect(tree).toMatchSnapshot();
});
```

### Unit Testing  Example

We can select an element with a `data-testid` properties in the component.

```jsx
import React from "react";
import Section from "@/page/section";

it("should show Hello World", () => {
  render(<Section />);
  const element = screen.getByTestId(`hello-world`);
  expect(element.textContent).toContain("Hello World");
});
```

### Testing a Component with Redux Store

To test a component with redux stores, we can use redux-mock-store.

```jsx
import React from "react";
import configureMockStore from "redux-mock-store";
import { Provider } from "react-redux";
import Profile from "@/page/profile";

let store;
const mockStore = configureMockStore();

beforeEach(() => {
  store = mockStore({
    user: {
      first_name: "John",
      last_name: "Doe",
    }
  });
  user = store.getState();
});

// Then we can render it with store passed to the provider
it("should show user first and last name", () => {
  const { getByText } = render(
    <Provider store={store}>
      <Profile />
    </Provider>
  );
  expect(getByText(user.first_name)).toBeInTheDocument();
  expect(getByText(user.last_name)).toBeInTheDocument();
});
```

### Handle Next.js Dynamic Import

If you want to test a component and that component contain a dynamic imports from `next/dynamic`, we can mock it like this to prevent import errors.

This mocks the dynamic imports to use `require`instead.

```jsx
// Mock Next Dynamic Import (Modified version of https://stackoverflow.com/a/66793989)
jest.mock("next/dynamic", () => ({
  __esModule: true,
  default: (...props) => {
    const modulePath = props[1].loadableGenerated.modules[0];
    const Component = require(modulePath).default;
    return Component;
  },
}));
```

To read more about mock functions you can check the [Official Jest Documentation](https://jestjs.io/docs/mock-functions).
