Jest测试中styled-components报TypeError: 读取undefined的length属性失败
问题
我正尝试为项目实现Jest测试,但运行测试时出现错误。我要测试的代码中并没有length方法,看起来错误源自styled-components。是否有解决方法?或者我对错误的理解有误?
测试代码
import React from "react"; import { render, screen } from "@testing-library/react"; import ChatBubblesContainer from "./ChatBubblesContainer"; let chats = []; const mockUseContext = jest.fn().mockImplementation(() => ({ chats: [], })); React.useContext = mockUseContext; describe("test", () => { test("render", () => { render(<ChatBubblesContainer />); expect(screen.getByTestId("bubbles-container")).toBeInTheDocument(); }); });
错误信息
TypeError: Cannot read properties of undefined (reading 'length') 20 | describe("test", () => { 21 | test("render", () => { > 22 | render(<ChatBubblesContainer />); | ^ 23 | expect(screen.getByTestId("bubbles-container")).toBeInTheDocument(); 24 | }); 25 | }); at charCodeAt (node_modules/styled-components/src/utils/hash.js:13:22) at e.hash [as generateAndInjectStyles] (node_modules/styled-components/src/models/ComponentStyle.js:80:53) at generateAndInjectStyles (node_modules/styled-components/src/models/StyledComponent.js:87:22) at node_modules/styled-components/src/models/StyledComponent.js:129:30 at displayName (node_modules/styled-components/src/models/StyledComponent.js:247:14) at renderWithHooks (node_modules/react-dom/cjs/react-dom.development.js:16305:18)
解决方案
这个错误是因为你直接替换了React.useContext,破坏了styled-components内部依赖的上下文机制。可以用以下几种方法解决:
- 用jest.spyOn替代直接赋值:不要直接覆盖全局的React.useContext,用spyOn模拟并在测试后恢复,避免影响其他依赖:
import React from "react"; import { render, screen } from "@testing-library/react"; import ChatBubblesContainer from "./ChatBubblesContainer"; describe("test", () => { test("render", () => { const mockUseContext = jest.spyOn(React, 'useContext') .mockImplementation(() => ({ chats: [] })); render(<ChatBubblesContainer />); expect(screen.getByTestId("bubbles-container")).toBeInTheDocument(); mockUseContext.mockRestore(); }); });
- 单独模拟自定义上下文:找到项目中你自己定义的Chat上下文,用它的Provider包裹组件来传递模拟值,而非修改全局useContext:
import React from "react"; import { render, screen } from "@testing-library/react"; import ChatBubblesContainer from "./ChatBubblesContainer"; import { ChatContext } from './ChatContext'; // 导入你的上下文 describe("test", () => { test("render", () => { render( <ChatContext.Provider value={{ chats: [] }}> <ChatBubblesContainer /> </ChatContext.Provider> ); expect(screen.getByTestId("bubbles-container")).toBeInTheDocument(); }); });
- 版本兼容性排查:尝试升级styled-components到与当前React版本匹配的稳定版,部分旧版本可能存在Jest测试时的上下文兼容问题。
内容的提问来源于stack exchange,提问作者MySQLNewbie
相关产品推荐
相关产品推荐

