Reputation: 834
I'm using NextJS and I'm trying to test the ClientPortal
component. I'm using Jest and React Testing Library for testing.
Here's the ClientPortal
component:
import { useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
export default function ClientPortal({ children, selector }) {
const ref = useRef();
const [mounted, setMounted] = useState(false);
useEffect(() => {
ref.current = document.querySelector(selector);
setMounted(true);
}, [selector]);
return mounted ? createPortal(children, ref.current) : null;
}
How can this be tested using Jest?
Upvotes: 0
Views: 432
Reputation: 102207
First, make sure the testEnvironment
configuration is jsdom
. For jestjs v26, it's jsdom
by default. For jestjs v27, follow this guide to setup the testEnvironment
configuration.
The test method is very straightforward. Create a DOM container to store the portal. Query the DOM element and assert whether it exists.
index.jsx
:
import { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
export default function ClientPortal({ children, selector }) {
const ref = useRef();
const [mounted, setMounted] = useState(false);
useEffect(() => {
ref.current = document.querySelector(selector);
setMounted(true);
}, [selector]);
return mounted ? createPortal(children, ref.current) : null;
}
index.test.jsx
:
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import ClientPortal from './';
function TestChild() {
return <div>child</div>;
}
describe('69550058', () => {
test('should pass', () => {
const main = document.createElement('main');
const portalContainer = document.createElement('div');
portalContainer.id = 'portal-container';
document.body.appendChild(portalContainer);
const { container } = render(
<ClientPortal selector={'#portal-container'}>
<TestChild />
</ClientPortal>,
{ container: document.body.appendChild(main) }
);
expect(screen.getByText(/child/)).toBeInTheDocument();
expect(portalContainer.innerHTML).toEqual('<div>child</div>');
expect(container).toMatchInlineSnapshot(`<main />`);
});
});
test result:
PASS examples/69550058/index.test.jsx (8.941 s)
69550058
✓ should pass (33 ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.jsx | 100 | 100 | 100 | 100 |
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 1 passed, 1 total
Time: 9.624 s, estimated 11 s
package versions:
"jest": "^26.6.3",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"@testing-library/react": "^11.2.2",
Upvotes: 1