TypeScript下React单元测试类型报错与用例失败问题排查
问题排查结果
你的测试全部失败是3个写法错误叠加导致的:
- 触发TS报错的直接原因:
getAllByAltText方法的返回值是匹配到的所有元素组成的数组,类型为HTMLImageElement[],数组类型本身不存在src属性,只有数组内的单个图片元素才有这个属性,直接在返回结果上调.src必然触发类型错误。 - 其余三个文本/标题测试运行失败的原因:断言方法名拼写错误,Testing Library 提供的DOM存在性断言正确写法是
toBeInTheDocument(),你全部写成了toBeInDocument(),缺失了中间的The,运行时会找不到这个匹配器。 - 图片测试的断言逻辑写串:
toBeInTheDocument()只用来判断元素是否被渲染到文档中,不能把src属性的校验逻辑嵌套在这个断言的调用链里。
额外注意:DOM原生的
img.src属性会自动把属性值补全为当前域名下的绝对路径,哪怕你传入的是相对/跨域地址,直接读取src属性和你传入的原始url做比对很容易出现预期外的不匹配,更推荐用官方提供的toHaveAttribute匹配器直接校验元素上的src属性原始值。
修复方案
- 因为当前组件内只有1张alt匹配「cute cat」的图片,把查询方法从返回数组的
getAllByAltText换成返回单个元素的getByAltText即可解决TS类型报错。如果确实需要查询多个同规则元素,需要通过数组下标取出单个元素(例如screen.getAllByAltText(...)[0])后再访问属性。 - 全局替换所有写错的
toBeInDocument()为正确的toBeInTheDocument()。 - 拆分图片测试的断言,先判断图片存在,再单独校验src属性值。
修正后的Card.test.tsx完整代码
import { render, screen } from "@testing-library/react"; import Card from "../Card"; const cardProps = { name: "Sydney", phone: "111-111-1111", email: "this@that.com", image: { url: "https://images.unsplash.com/photo-1573865526739-10659fec78a5?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=830&q=80", alt: "cute cat", }, favored: false, }; describe("Card", () => { test("should show name of cat", () => { render(<Card {...cardProps} />); expect( screen.getByRole("heading", { name: "Sydney", }) ).toBeInTheDocument(); }); test("should show phone number", () => { render(<Card {...cardProps} />); expect(screen.getByText(/111-111-1111/i)).toBeInTheDocument(); }); test("should show email", () => { render(<Card {...cardProps} />); expect(screen.getByText(/this@that.com/i)).toBeInTheDocument(); }); test("should show image with correct source", () => { render(<Card {...cardProps} />); const catImage = screen.getByAltText<HTMLImageElement>(/cute cat/i); expect(catImage).toBeInTheDocument(); expect(catImage).toHaveAttribute("src", cardProps.image.url); }); });
内容的提问来源于stack exchange,提问作者code4cash
相关产品推荐
相关产品推荐

