Testing Guidelines
Some useful resources and examples on testing.
Test Setup with SSR
NextJS deploys an application in 2 parts:
- Server Side: Runs in nodeJS
- Client Side: Runs in the browser
Proper config requires that test environments are set accordingly. Recall that Node and the Browser are NOT functionally identical. Node does not perfectly replicate all items in the DOM and the browser does not have direct access to things like the DB.
As of Dec 1, 2021, we configure
.tsx
files to run in the browser, and .ts
to run in node. You can configure this behaviour in the testMatch
param in the jest.config.js
fileRendering and Searching for Elements in the DOM
Use the
render
method from testing library around a React component. Here's a good example:import React from 'react';
import axios from 'axios';
import { MenuLinks } from '../../../../../src/components/global/Header/Menu';
import { useSession } from 'next-auth/react';
import { BANKLESS } from '../../../../../src/constants/Bankless';
import { guilds as guildsStub } from '../../../../stubs/guilds.stub';
import { render, screen } from '@testing-library/react';
jest.mock('next-auth/react', () => ({
useSession: jest.fn(),
}));
it('Shows the selector if signed in and if there are customers', () => {
// stub API calls using jest.spyOn
jest.spyOn(axios, 'get').mockReturnValue(Promise.resolve({
data: guildsStub
}
));
// using the mockImplementation functionality to replace useSession
const useSessionTest = useSession as typeof useSession & any;
useSessionTest.mockImplementation(() => ({ status: 'Done', data: {} }));
// using mockReturnValueOnce when we have multiple useState calls
jest.spyOn(React, 'useState')
.mockReturnValueOnce([[BANKLESS], () => console.log('setCustomers')])
.mockReturnValueOnce([guildsStub, () => console.log('setGuilds')]);
// call the render method on the element to start the test properly
render(<MenuLinks isOpen={false}/>);
// https://testing-library.com/docs/queries/about
// 'role' is predefined by element, you can set the name by using
// aria-label
const input = screen.getByRole('combobox', { name: 'dao-selector' });
expect(input).toBeVisible();
});
Appendix: Some general notes on Jest
This is for Vue JS but might be of help