Jest测试React Dashboard组件时遇clientHeight未定义错误求助
Hey there! Let's break down why you're hitting this error and walk through actionable fixes to get your tests running smoothly.
The Root Cause
Your tableHeight method is trying to access document.getElementsByClassName('nep-header')[0].clientHeight, but in the Jest testing environment, there's no element with the nep-header class rendered. That means document.getElementsByClassName('nep-header') returns an empty array, so [0] is undefined—hence the error when you try to get clientHeight from it.
Solution 1: Quick Fix - Mock the nep-header Element in Tests
The fastest way to get your tests passing is to create a mock nep-header element before running your tests, so the DOM query finds a valid element. Add this to your test file:
beforeEach(() => { // Create a mock header element and add it to the test DOM const mockHeader = document.createElement('div'); mockHeader.className = 'nep-header'; mockHeader.style.height = '80px'; // Set a dummy height for testing document.body.appendChild(mockHeader); // Mock window.innerHeight to avoid unexpected values Object.defineProperty(window, 'innerHeight', { writable: true, value: 1080, }); }); afterEach(() => { // Clean up the mock element after each test to avoid cross-test pollution document.body.removeChild(document.querySelector('.nep-header')); });
Solution 2: Long-Term Fix - Refactor to Avoid Direct DOM Queries
Directly querying the DOM with document.getElementsByClassName isn't the most React-friendly approach. Instead, use React refs (if the header is part of your component tree) or pass the header height as a prop from a parent component. Here's how you could adjust your tableHeight method:
First, add a ref to your component (if the header is inside your Dashboard component; if it's external, pass the height as a prop):
class Dashboard extends React.Component { constructor(props) { super(props); this.headerRef = React.createRef(); // Add this ref // ... rest of your constructor code } tableHeight() { // Guard clause: exit if ref doesn't exist if (!this.headerRef.current) return; const headerHeight = this.headerRef.current.clientHeight; const tableHeight = `${window.innerHeight - headerHeight - 20}px`; const tableElement = document.getElementById("pr"); if (tableElement) tableElement.style.height = tableHeight; } // ... rest of your component code }
Then attach the ref to the nep-header element (if it's part of your component; check Neptune library docs if it's a third-party component that accepts refs).
Solution 3: Mock the DOM Query Directly
If you don't want to modify your component code right now, you can mock document.getElementsByClassName to return a mock element with a clientHeight property:
it("should render initial layout", () => { // Mock the getElementsByClassName call to return a dummy header element jest.spyOn(document, 'getElementsByClassName').mockReturnValue([{ clientHeight: 80 }]); const component = shallow(<Dashboard />); expect(component.getElements()).toMatchSnapshot(); // Restore the original method after the test jest.restoreAllMocks(); });
Bonus: Fix Your Async Test
I noticed your second test has some async rendering issues. Here's a cleaned-up version using React Testing Library's waitFor to ensure the test waits for API data to load:
import { waitFor } from '@testing-library/react'; it("test to render Dashboard component", async () => { axios.post.mockResolvedValue({ data: [{ Companyname: "xyz", accurate: "Positive", cik: "123" }], status: 200, statusText: "OK" }); const { getByText } = render(<Dashboard />); // Wait for the company data to load and render await waitFor(() => getByText("xyz")); expect(getByText("xyz")).toBeInTheDocument(); });
内容的提问来源于stack exchange,提问作者chaitanya

