reactjs - 如何使用 jest 对作为 prop 传递的函数进行单元测试
问题描述
我想在 Student 组件中测试 addTagclick
import React, { useState } from "react";
import "../stylesheets/Student.scss";
import AddTag from "./AddTag";
import Tag from "./Tag";
const Student = ({ student, addTagClick, tags }) => {
tags = tags.filter((tag) => tag.studentId === student.id);
const averageGrade =
student.grades.reduce((acc, grade) => {
return parseInt(acc) + parseInt(grade);
}) / student.grades.length;
const [isViewScores, setIsViewScores] = useState(false);
const viewScoreClick = () => {
setIsViewScores((prev) => !prev);
};
return (
<article className="student">
<figure>
<img src={student.pic} alt="student" />
</figure>
<aside>
<h2>
{student.firstName} {student.lastName}
</h2>
<ul>
<li>Email: {student.email}</li>
<li>Company: {student.company}</li>
<li>Skill: {student.skill}</li>
<li>
Average: {averageGrade}%
<>
{isViewScores && (
<ul className="scores">
{student.grades.map((grade, index) => {
return (
<li key={index}>
Test {index + 1}: {grade}%
</li>
);
})}
</ul>
)}
</>
</li>
</ul>
<div className="tags-container">
{tags.map((tag) => (
<Tag tag={tag} key={tag.id} />
))}
</div>
<AddTag studentId={student.id} addTagClick={addTagClick} />
</aside>
<button onClick={viewScoreClick} className="view-scores-btn">
{isViewScores ? "-" : "+"}
</button>
</article>
);
};
export default Student;
AddTag 组件具有 addTagClick,它将将 newTag 作为参数传递给表单提交
import React, { useState } from "react";
import { generateId } from "../helper";
import Input from "./Input";
const AddTag = ({ studentId, addTagClick }) => {
const [tag, setTag] = useState("");
const handleInputChange = ({ target }) => {
setTag(target.value);
};
const onSubmitClick = (e) => {
e.preventDefault();
const newTag = {
tag: tag,
id: generateId(),
studentId: studentId,
};
if (tag) {
addTagClick(newTag);
}
setTag("");
};
return (
<form data-testid="form" onSubmit={onSubmitClick}>
<Input
className="add-tag-input"
placeholder="Add a tag"
type="text"
value={tag}
onChange={handleInputChange}
/>
<button>add tag</button>
</form>
);
};
export default AddTag;
最后,在 StudentsContainer 组件中,将 newTag 添加到 tags 状态
import React, { useState, useMemo } from "react";
import Student from "./Student";
import Input from "./Input";
import "../stylesheets/StudentsContainer.scss";
const StudentsContainer = ({ students }) => {
const [searchByName, setSearchByName] = useState("");
const [searchByTags, setSearchByTags] = useState("");
const [tags, setTags] = useState([]);
const addTagClick = (newTag) => {
setTags((prevTags) => [...prevTags, newTag]);
};
students = useMemo(
() =>
students.filter(
({ firstName, lastName, id }) =>
searchByName.length < 2 ||
(firstName + " " + lastName)
.toLowerCase()
.includes(searchByName.toLowerCase())
),
[students, searchByName]
);
const renderStudentsBySearch = () => {
if (searchByTags.length < 2) {
return students;
} else {
return students.filter((student) => {
for (let i = 0; i < tags.length; i++) {
const tag = tags[i];
if (tag.studentId === student.id && tag.tag.includes(searchByTags)) {
return student;
}
}
});
}
};
return (
<section className="students-container">
<Input
value={searchByName}
placeholder="Search by name"
onChange={({ target }) => setSearchByName(target.value)}
/>
<Input
className="tag-input"
value={searchByTags}
placeholder="Search by tag"
onChange={({ target }) => setSearchByTags(target.value)}
/>
<div className="students">
{renderStudentsBySearch().map((student) => (
<Student
tags={tags}
addTagClick={addTagClick}
key={student.id}
student={student}
/>
))}
</div>
</section>
);
};
export default StudentsContainer;
这就是我到目前为止所拥有的,并且测试失败说调用次数:0
import React from "react";
import { render, fireEvent } from "@testing-library/react";
import Student from "../Student";
import { generateId } from "../../helper";
const mockStudent = {
firstName: "Yoda",
lastName: "Li",
email: "yoda.li@gmail.com",
city: "SF",
company: "Dog",
pic: "https://dog.com",
skill: "eat",
id: "8",
grades: ["100", "88", "99", "89", "98", "100", "88", "98"],
};
const mockTags = [
// { tag: "tag1", id: "8" },
// { tag: "tag1", id: "7" },
];
describe("Student", () => {
test("addTagClick is called with button click or with enter key, and newTag is added", () => {
const addTagClickMock = jest.fn();
const { getByPlaceholderText, getByText, getByTestId } = render(
<Student
student={mockStudent}
tags={mockTags}
addTagClick={addTagClickMock}
/>
);
const tagInput = getByPlaceholderText("Add a tag");
const addTagButton = getByText("add tag");
tagInput.value = "tag1";
fireEvent.click(addTagButton);
expect(addTagClickMock).toHaveBeenCalled();
expect(addTagClickMock).toHaveBeenCalledWith({
tag: tagInput.value,
id: generateId(),
studentId: mockStudent.id,
});
});
});
谢谢你的帮助!
解决方案
推荐阅读
- cumulocity - 子租户 REST 端点的微服务下标不起作用
- tensorflow - 将 tf.keras.applications 中定义模型的架构用于非图像数据集的最佳方法是什么?
- python - 如何使用 python 获得显着性测试(例如 p 值)?
- php - 将一个数组值存储在php中的另一个对象数组中
- javascript - 使用 HERE MAP API 作为航点动态传递经度/纬度
- rest - okta 与 spring mvc rest api oauth2 集成
- java - 休眠加速插入
- java - ReflectionUtils 如何替换已弃用的方法?
- r - R 测量距海岸线的距离
- javascript - 你能做 .prev() 减去一个数字吗