In this example, Im mocking the open
function of the window
object, then in the actual test block, Im returning an object with a focus
property that also Im mocking.
Describe('some test', () => {
let spyWindowOpen;
beforeEach(() => {
spyWindowOpen = jest.spyOn(window, 'open');
});
afterEach(() => {
spyWindowOpen.mockRestore();
});
it('some other test', () => {
const open = jest.fn((...args) => ({ focus: jest.fn() }));
spyWindowOpen.mockImplementation(open);
render(<YourComponent />);
// ... the rest of your code
expect(open).toBeCalled();
expect(open).toBeCalledWith('http://www.google.com', '_blank');
});
})
Some references:
- https://jestjs.io/docs/mock-function-api#mockfnmockimplementationfn
- https://jestjs.io/docs/upgrading-to-jest28#jestfn
const input = screen.getByRole('textbox', { name: /some field/i });
// always remember to await this kind of actions
await userEvent.type(input, 'abc');
expect(input).toHaveValue('');
Also, there are sometimes where we want to clear whatever we typed, for that we use userEvent.clear
const input = screen.getByRole('textbox', { name: /some field/i });
// always remember to await this kind of actions
await userEvent.type(input, 'abc');
expect(input).toHaveValue('');
await userEvent.clear(input)
...
References
const alertMock = jest.spyOn(window, "alert").mockImplementation();
render(<App />);
userEvent.click(screen.getByRole("button", { name: LOGIN_BUTTON_TEXT }));
expect(alertMock).toHaveBeenCalled();
Just create a file called .env.test.local
Jest will read it automatically
Reference:
npx jest src/features/search/__tests__/search-view-toolbar.test.tsx --coverage --detectOpenHandles --runInBand --watch
First, add a reusable function inside your Jest setup file:
// Define the resizeTo method if it's not available
global.resizeTo = (width, height) => {
// eslint-disable-next-line fp/no-mutating-assign
Object.assign(global, {
innerHeight: height,
innerWidth: width,
}).dispatchEvent(new Event('resize'));
};
Now when doing the tests in your file:
beforeEach(() => {
jest.clearAllMocks();
});
afterEach(() => {
jest.restoreAllMocks();
});
afterAll(() => {
jest.resetAllMocks();
// this is to reset the viewport to the default size
global.resizeTo(1024, 768);
});
.... other code
it('should be visible the PriceBreakdown header when viewport is within the mobile device range.', async () => {
// Resize the viewport to a width that matches the media query breakpoint
global.resizeTo(500, global.innerHeight);
render(<CheckoutCartInfo />, {
initialState: mockedState,
});
const element = screen.getByTestId('price-breakdown-header');
// data-pmtest-id='price-breakdown-header'
expect(element).toBeVisible();
});
Sometimes we need to force a rerender, we can do it like this:
const { user, rerender } = render(
<Wrapper>
<SearchViewToolbar {...initProps} />
</Wrapper>,
{
initialState: mockedState,
}
);
... other logic
// Rerender with cleared search value to simulate the state update
rerender(
<Wrapper>
<SearchViewToolbar {...{ ...initProps, searchValue: '' }} />
</Wrapper>
);
Sometimes we need to mock a call to certain functionality, for that we need to do this in your test file"
<!-- in case you just want to mock the functionatly and you are not planning to do anything -->
// Mock @/lib/utils once for all tests
jest.mock('@/lib/utils', () => ({
__esModule: true,
loadGoogleAPI: jest.fn(),
}));
<!-- You can place that inside a beforeAll -->
<!-- in case you need to do something or mock the implementation for the dependency do this instead -->
// first at the top of the file call that dependency
import {dependency} from "../hook/sample"
// now mock the entire module
jest.mock("../hook/sample")
// later in your code call the mocked dependency
(dependency as Jest.Mock).mockReturnValue(
mockedValue
);