无法 运行 测试连接的组件
Unable to run tests on connected components
我正在使用 MERN 堆栈和 Redux。我正在尝试为各种组件编写一些测试用例。对于任何已连接的,我都会收到错误...
“无法在“Connect(Subject)”的上下文中找到“store”。要么将根组件包装在 a 中,要么将自定义 React 上下文提供程序传递给 Connect(Subject) 并将相应的 React 上下文使用者传递给在连接选项中。"
我已经尝试将其包装在提供程序中,但我仍然收到相同的消息。有人知道如何解决这个问题吗?
测试
import React from "react";
import { shallow } from "enzyme";
import { mount } from "enzyme";
import Provider from "react";
import { createStore, applyMiddleware } from "redux";
import Subject from "../components/layout/Subject";
import thunk from "redux-thunk";
import combineReducers from "../reducers/index";
const store = createStore(combineReducers, undefined, applyMiddleware(thunk));
it("Subject should render without errors", () => {
const component = mount(
<Provider store={store}>
<Subject />
</Provider>
);
const wrapper = component.find("#Subject");
expect(wrapper.length).toBe(1);
});
组件
import React, { Component } from "react";
import PropTypes from "prop-types";
import GoogleSearch from "./GoogleSearch";
import { connect } from "react-redux";
import { fetchLatestSubjects } from "../../actions/subject";
import { fetchTopicSubjects } from "../../actions/subject";
import { fetchTopicComments } from "../../actions/comment";
import { fetchComments } from "../../actions/comment";
import { rateSubject } from "../../actions/subject";
import { fetchUsers } from "../../actions/authActions";
import { rateUser } from "../../actions/authActions";
import { rateComment } from "../../actions/comment";
import { trueVote } from "../../actions/subject";
import { mostlyTrueVote } from "../../actions/subject";
import { mostlyFalseVote } from "../../actions/subject";
import { halfAndHalfVote } from "../../actions/subject";
import { falseVote } from "../../actions/subject";
class Subject extends Component {
// on loading the subjects and comments
// are fetched from the database
componentDidMount() {
this.props.fetchLatestSubjects();
this.props.fetchComments();
this.props.fetchUsers();
console.log(
fetch("https://extreme-ip-lookup.com/json").then((res) => res.json())
);
}
constructor(props) {
super(props);
this.state = {
// set inital state for subjects
// description, summary and comments all invisible
viewDesription: -1,
viewSummary: -1,
comments: [],
topic: "subjects",
};
}
componentWillReceiveProps(nextProps) {
// new subject and comments are added to the top
// of the arrays
if (nextProps.newPost) {
this.props.subjects.unshift(nextProps.newPost);
}
if (nextProps.newPost) {
this.props.comments.unshift(nextProps.newPost);
}
}
clickHandler = (id) => {
// when a subject title is clicked pass in its id
const { viewDescription } = this.state;
this.setState({ comments: [] });
var temp = [];
// get the details of the author of the subject and save to state
const subject = this.props.subjects.find((subject) => subject._id === id);
const user = this.props.users.find((user) => user._id === subject.author);
// save comments for subject to temp array
var i;
for (i = 0; i < this.props.comments.length; i++) {
if (this.props.comments[i].subject === id) {
temp.unshift(this.props.comments[i]);
}
}
console.log(temp);
// for each comment add a property with the authors name
temp.forEach((comment) => {
var commentAuthor = this.props.users.find(
(user) => user._id === comment.author
);
comment.authName = commentAuthor.name;
});
// save the subject id to local storage
// this is done incase a new comment is added
// then the subject associated with it can be retrieved
// and added as a property of that comment
localStorage.setItem("passedSubject", id);
localStorage.setItem("passedTopic", subject.topic);
// add all changes to the state
this.setState({
viewDescription: viewDescription === id ? -1 : id,
comments: temp,
subAuthor: user.name,
authRating: user.rating,
authNoOfVotes: user.noOfVotes,
});
};
// hovering on and off subjects toggles the visibility of the summary
hoverHandler = (id) => {
this.setState({ viewSummary: id });
};
hoverOffHandler = () => {
this.setState({ viewSummary: -1 });
};
rateHandler = (id, rate, item) => {
if (item === "subject") {
// this function rates the subject and the author
const subject = this.props.subjects.find((subject) => subject._id === id);
const author = this.props.users.find(
(user) => user._id === subject.author
);
// call the rateSubject and rateUser functions
this.props.rateSubject(id, rate, subject.noOfVotes, subject.rating);
this.props.rateUser(author._id, rate, author.noOfVotes, author.rating);
console.log(author.name);
alert("Thank you for rating this subject.");
} else if (item === "comment") {
const comment = this.props.comments.find((comment) => comment._id === id);
const author = this.props.users.find(
(user) => user._id === comment.author
);
// call the rateComment and rateUser functions
this.props.rateComment(id, rate, comment.noOfVotes, comment.rating);
this.props.rateUser(author._id, rate, author.noOfVotes, author.rating);
console.log(author.name);
alert("Thank you for rating this comment.");
}
};
voteHandler = (id, currVote, vote) => {
if (vote === "True") {
console.log(id, currVote, vote);
this.props.trueVote(id, currVote);
alert("Thanks for voting!");
window.location.reload(false);
} else if (vote === "False") {
console.log(id, currVote, vote);
this.props.falseVote(id, currVote);
alert("Thanks for voting!");
window.location.reload(false);
} else if (vote === "mostlyFalse") {
console.log(id, currVote, vote);
this.props.mostlyFalseVote(id, currVote);
alert("Thanks for voting!");
window.location.reload(false);
} else if (vote === "mostlyTrue") {
console.log(id, currVote, vote);
this.props.mostlyTrueVote(id, currVote);
alert("Thanks for voting!");
window.location.reload(false);
} else if (vote === "halfAndHalf") {
console.log(id, currVote, vote);
this.props.halfAndHalfVote(id, currVote);
alert("Thanks for voting!");
window.location.reload(false);
}
};
render() {
const subjectItems = this.props.subjects.map((subject) => {
// if the state equals the id set to visible if not set to invisible
var view = this.state.viewDescription === subject._id ? "" : "none";
var hover = this.state.viewSummary === subject._id ? "" : "none";
var comments = this.state.comments;
var subjectAuthor = this.state.subAuthor;
var authRating = this.state.authRating;
var authNoOfVotes = this.state.authNoOfVotes;
var className = "";
if (subject.category === "Education") {
className = "Education";
} else if (subject.category === "Environment") {
className = "Environment";
} else if (subject.category === "Politics") {
className = "Politics";
} else if (subject.category === "Health") {
className = "Health";
} else if (subject.category === "Other") {
className = "Other";
}
return (
<div key={subject._id}>
<div
className={className}
onMouseEnter={() => this.hoverHandler(subject._id)}
onMouseLeave={() => this.hoverOffHandler()}
>
<p className="title" onClick={() => this.clickHandler(subject._id)}>
{subject.title}
</p>
<p className="vote" style={{ textAlign: "Right" }}>
Rating: {(subject.rating / subject.noOfVotes).toFixed(1)}/5
</p>
<p className="summary" style={{ display: hover }}>
{subject.summary}
</p>
</div>
<div className="truthResult" style={{ display: view }}>
<p className="false">
FALSE -{" "}
{(
(100 /
(subject.true +
subject.false +
subject.mostlyTrue +
subject.mostlyFalse +
subject.halfAndHalf)) *
subject.false
).toFixed(1)}
%
</p>
<p className="mostlyFalse">
MOSTLY FALSE -{" "}
{(
(100 /
(subject.true +
subject.false +
subject.mostlyTrue +
subject.mostlyFalse +
subject.halfAndHalf)) *
subject.mostlyFalse
).toFixed(1)}
%
</p>
<p className="halfAndHalf">
HALF AND HALF -{" "}
{(
(100 /
(subject.true +
subject.false +
subject.mostlyTrue +
subject.mostlyFalse +
subject.halfAndHalf)) *
subject.halfAndHalf
).toFixed(1)}
%
</p>
<p className="mostlyTrue">
MOSTLY TRUE -{" "}
{(
(100 /
(subject.true +
subject.false +
subject.mostlyTrue +
subject.mostlyFalse +
subject.halfAndHalf)) *
subject.mostlyTrue
).toFixed(1)}
%
</p>
<p className="true">
TRUE -{" "}
{(
(100 /
(subject.true +
subject.false +
subject.mostlyTrue +
subject.mostlyFalse +
subject.halfAndHalf)) *
subject.true
).toFixed(1)}
%
</p>
</div>
<div className="subjectBody " style={{ display: view }}>
<div className="leftSubjectBody">
<div className="subjectAuthor">
<p className="author">
Subject created by: {subjectAuthor} -{" "}
{(authRating / authNoOfVotes).toFixed(1)}/5 Star user
{/* <br /> {subject.date} */}
</p>
</div>
<div className="subjectDescription">
<p className="description">{subject.description}</p>
</div>
<div className="subjectLinks">
Supporting Link: <br />
<a href={subject.links} target="blank">
{subject.links}
</a>
</div>
</div>
<div className="rightSubjectBody">
<div className="rate">
<p>
<b>Rate this subject</b>
</p>
<button
onClick={() => this.rateHandler(subject._id, 1, "subject")}
>
1
</button>
<button
onClick={() => this.rateHandler(subject._id, 2, "subject")}
>
2
</button>
<button
onClick={() => this.rateHandler(subject._id, 3, "subject")}
>
3
</button>
<button
onClick={() => this.rateHandler(subject._id, 4, "subject")}
>
4
</button>
<button
onClick={() => this.rateHandler(subject._id, 5, "subject")}
>
5
</button>
</div>
<div className="voting">
<p>
Do you think this subject question is false, mostly false,
half and half, mostly true or true, based on the evidence
provided and your own reseach in the area? Please vote below
and leave comments.
</p>
<div
className="voteButton"
onClick={() =>
this.voteHandler(subject._id, subject.false, "False")
}
>
FALSE
</div>
<div
className="voteButton"
onClick={() =>
this.voteHandler(
subject._id,
subject.mostlyFalse,
"mostlyFalse"
)
}
>
MOSTLY FALSE
</div>
<div
className="voteButton"
onClick={() =>
this.voteHandler(
subject._id,
subject.halfAndHalf,
"halfAndHalf"
)
}
>
HALF AND HALF
</div>
<br />
<div
className="voteButton"
onClick={() =>
this.voteHandler(
subject._id,
subject.mostlyTrue,
"mostlyTrue"
)
}
>
MOSTLY TRUE
</div>
<div
className="voteButton"
onClick={() =>
this.voteHandler(subject._id, subject.true, "True")
}
>
TRUE
</div>
</div>
</div>
<div className="subjectComments">
<p style={{ fontWeight: "bold" }}>Comments:</p>
{comments.map((comment, i) => {
return (
<div key={i} className="singleComment">
<p>
{comment.title} - Comment rating :{" "}
{(comment.rating / comment.noOfVotes).toFixed(1)}/5
<br />
{comment.comment}
<br />
Comment by : {comment.authName} - This user has a rating
of {(comment.rating / comment.noOfVotes).toFixed(1)}/5
STARS
</p>
<div className="rate">
Rate this comment :{" "}
<button
onClick={() =>
this.rateHandler(comment._id, 1, "comment")
}
>
1
</button>
<button
onClick={() =>
this.rateHandler(comment._id, 2, "comment")
}
>
2
</button>
<button
onClick={() =>
this.rateHandler(comment._id, 3, "comment")
}
>
3
</button>
<button
onClick={() =>
this.rateHandler(comment._id, 4, "comment")
}
>
4
</button>
<button
onClick={() =>
this.rateHandler(comment._id, 5, "comment")
}
>
5
</button>
</div>
</div>
);
})}
<br />
<a href="/addcomment">
<div className="buttonAddComment">ADD COMMENT</div>
</a>
</div>
</div>
</div>
);
});
return (
<div id="Subject">
<GoogleSearch />
{subjectItems}
</div>
);
}
}
Subject.propTypes = {
fetchLatestSubjects: PropTypes.func.isRequired,
fetchTopicSubjects: PropTypes.func.isRequired,
fetchTopicComments: PropTypes.func.isRequired,
fetchComments: PropTypes.func.isRequired,
fetchUsers: PropTypes.func.isRequired,
rateSubject: PropTypes.func.isRequired,
rateComment: PropTypes.func.isRequired,
rateUser: PropTypes.func.isRequired,
trueVote: PropTypes.func.isRequired,
falseVote: PropTypes.func.isRequired,
subjects: PropTypes.array.isRequired,
comments: PropTypes.array.isRequired,
users: PropTypes.array.isRequired,
newPost: PropTypes.object,
};
const mapStateToProps = (state) => ({
subjects: state.subjects.items,
newSubject: state.subjects.item,
comments: state.comments.items,
users: state.auth.users,
newComment: state.comments.item,
});
// export default Subject;
export default connect(mapStateToProps, {
fetchLatestSubjects,
fetchTopicSubjects,
fetchTopicComments,
fetchComments,
fetchUsers,
rateSubject, // rate subject
rateUser,
rateComment,
trueVote,
mostlyTrueVote,
falseVote,
mostlyFalseVote,
halfAndHalfVote,
})(Subject, Comment);
这就是我们在 React 测试库中的做法。您可以通过相应地替换实用函数将其转换为酶。
- 为需要渲染的组件提供 store。
it('renders with redux', () => {
render(<Provider store={store}>
<ReduxCode />
</Provider>);
//further code...
})
我正在使用 MERN 堆栈和 Redux。我正在尝试为各种组件编写一些测试用例。对于任何已连接的,我都会收到错误...
“无法在“Connect(Subject)”的上下文中找到“store”。要么将根组件包装在 a 中,要么将自定义 React 上下文提供程序传递给 Connect(Subject) 并将相应的 React 上下文使用者传递给在连接选项中。"
我已经尝试将其包装在提供程序中,但我仍然收到相同的消息。有人知道如何解决这个问题吗?
测试
import React from "react";
import { shallow } from "enzyme";
import { mount } from "enzyme";
import Provider from "react";
import { createStore, applyMiddleware } from "redux";
import Subject from "../components/layout/Subject";
import thunk from "redux-thunk";
import combineReducers from "../reducers/index";
const store = createStore(combineReducers, undefined, applyMiddleware(thunk));
it("Subject should render without errors", () => {
const component = mount(
<Provider store={store}>
<Subject />
</Provider>
);
const wrapper = component.find("#Subject");
expect(wrapper.length).toBe(1);
});
组件
import React, { Component } from "react";
import PropTypes from "prop-types";
import GoogleSearch from "./GoogleSearch";
import { connect } from "react-redux";
import { fetchLatestSubjects } from "../../actions/subject";
import { fetchTopicSubjects } from "../../actions/subject";
import { fetchTopicComments } from "../../actions/comment";
import { fetchComments } from "../../actions/comment";
import { rateSubject } from "../../actions/subject";
import { fetchUsers } from "../../actions/authActions";
import { rateUser } from "../../actions/authActions";
import { rateComment } from "../../actions/comment";
import { trueVote } from "../../actions/subject";
import { mostlyTrueVote } from "../../actions/subject";
import { mostlyFalseVote } from "../../actions/subject";
import { halfAndHalfVote } from "../../actions/subject";
import { falseVote } from "../../actions/subject";
class Subject extends Component {
// on loading the subjects and comments
// are fetched from the database
componentDidMount() {
this.props.fetchLatestSubjects();
this.props.fetchComments();
this.props.fetchUsers();
console.log(
fetch("https://extreme-ip-lookup.com/json").then((res) => res.json())
);
}
constructor(props) {
super(props);
this.state = {
// set inital state for subjects
// description, summary and comments all invisible
viewDesription: -1,
viewSummary: -1,
comments: [],
topic: "subjects",
};
}
componentWillReceiveProps(nextProps) {
// new subject and comments are added to the top
// of the arrays
if (nextProps.newPost) {
this.props.subjects.unshift(nextProps.newPost);
}
if (nextProps.newPost) {
this.props.comments.unshift(nextProps.newPost);
}
}
clickHandler = (id) => {
// when a subject title is clicked pass in its id
const { viewDescription } = this.state;
this.setState({ comments: [] });
var temp = [];
// get the details of the author of the subject and save to state
const subject = this.props.subjects.find((subject) => subject._id === id);
const user = this.props.users.find((user) => user._id === subject.author);
// save comments for subject to temp array
var i;
for (i = 0; i < this.props.comments.length; i++) {
if (this.props.comments[i].subject === id) {
temp.unshift(this.props.comments[i]);
}
}
console.log(temp);
// for each comment add a property with the authors name
temp.forEach((comment) => {
var commentAuthor = this.props.users.find(
(user) => user._id === comment.author
);
comment.authName = commentAuthor.name;
});
// save the subject id to local storage
// this is done incase a new comment is added
// then the subject associated with it can be retrieved
// and added as a property of that comment
localStorage.setItem("passedSubject", id);
localStorage.setItem("passedTopic", subject.topic);
// add all changes to the state
this.setState({
viewDescription: viewDescription === id ? -1 : id,
comments: temp,
subAuthor: user.name,
authRating: user.rating,
authNoOfVotes: user.noOfVotes,
});
};
// hovering on and off subjects toggles the visibility of the summary
hoverHandler = (id) => {
this.setState({ viewSummary: id });
};
hoverOffHandler = () => {
this.setState({ viewSummary: -1 });
};
rateHandler = (id, rate, item) => {
if (item === "subject") {
// this function rates the subject and the author
const subject = this.props.subjects.find((subject) => subject._id === id);
const author = this.props.users.find(
(user) => user._id === subject.author
);
// call the rateSubject and rateUser functions
this.props.rateSubject(id, rate, subject.noOfVotes, subject.rating);
this.props.rateUser(author._id, rate, author.noOfVotes, author.rating);
console.log(author.name);
alert("Thank you for rating this subject.");
} else if (item === "comment") {
const comment = this.props.comments.find((comment) => comment._id === id);
const author = this.props.users.find(
(user) => user._id === comment.author
);
// call the rateComment and rateUser functions
this.props.rateComment(id, rate, comment.noOfVotes, comment.rating);
this.props.rateUser(author._id, rate, author.noOfVotes, author.rating);
console.log(author.name);
alert("Thank you for rating this comment.");
}
};
voteHandler = (id, currVote, vote) => {
if (vote === "True") {
console.log(id, currVote, vote);
this.props.trueVote(id, currVote);
alert("Thanks for voting!");
window.location.reload(false);
} else if (vote === "False") {
console.log(id, currVote, vote);
this.props.falseVote(id, currVote);
alert("Thanks for voting!");
window.location.reload(false);
} else if (vote === "mostlyFalse") {
console.log(id, currVote, vote);
this.props.mostlyFalseVote(id, currVote);
alert("Thanks for voting!");
window.location.reload(false);
} else if (vote === "mostlyTrue") {
console.log(id, currVote, vote);
this.props.mostlyTrueVote(id, currVote);
alert("Thanks for voting!");
window.location.reload(false);
} else if (vote === "halfAndHalf") {
console.log(id, currVote, vote);
this.props.halfAndHalfVote(id, currVote);
alert("Thanks for voting!");
window.location.reload(false);
}
};
render() {
const subjectItems = this.props.subjects.map((subject) => {
// if the state equals the id set to visible if not set to invisible
var view = this.state.viewDescription === subject._id ? "" : "none";
var hover = this.state.viewSummary === subject._id ? "" : "none";
var comments = this.state.comments;
var subjectAuthor = this.state.subAuthor;
var authRating = this.state.authRating;
var authNoOfVotes = this.state.authNoOfVotes;
var className = "";
if (subject.category === "Education") {
className = "Education";
} else if (subject.category === "Environment") {
className = "Environment";
} else if (subject.category === "Politics") {
className = "Politics";
} else if (subject.category === "Health") {
className = "Health";
} else if (subject.category === "Other") {
className = "Other";
}
return (
<div key={subject._id}>
<div
className={className}
onMouseEnter={() => this.hoverHandler(subject._id)}
onMouseLeave={() => this.hoverOffHandler()}
>
<p className="title" onClick={() => this.clickHandler(subject._id)}>
{subject.title}
</p>
<p className="vote" style={{ textAlign: "Right" }}>
Rating: {(subject.rating / subject.noOfVotes).toFixed(1)}/5
</p>
<p className="summary" style={{ display: hover }}>
{subject.summary}
</p>
</div>
<div className="truthResult" style={{ display: view }}>
<p className="false">
FALSE -{" "}
{(
(100 /
(subject.true +
subject.false +
subject.mostlyTrue +
subject.mostlyFalse +
subject.halfAndHalf)) *
subject.false
).toFixed(1)}
%
</p>
<p className="mostlyFalse">
MOSTLY FALSE -{" "}
{(
(100 /
(subject.true +
subject.false +
subject.mostlyTrue +
subject.mostlyFalse +
subject.halfAndHalf)) *
subject.mostlyFalse
).toFixed(1)}
%
</p>
<p className="halfAndHalf">
HALF AND HALF -{" "}
{(
(100 /
(subject.true +
subject.false +
subject.mostlyTrue +
subject.mostlyFalse +
subject.halfAndHalf)) *
subject.halfAndHalf
).toFixed(1)}
%
</p>
<p className="mostlyTrue">
MOSTLY TRUE -{" "}
{(
(100 /
(subject.true +
subject.false +
subject.mostlyTrue +
subject.mostlyFalse +
subject.halfAndHalf)) *
subject.mostlyTrue
).toFixed(1)}
%
</p>
<p className="true">
TRUE -{" "}
{(
(100 /
(subject.true +
subject.false +
subject.mostlyTrue +
subject.mostlyFalse +
subject.halfAndHalf)) *
subject.true
).toFixed(1)}
%
</p>
</div>
<div className="subjectBody " style={{ display: view }}>
<div className="leftSubjectBody">
<div className="subjectAuthor">
<p className="author">
Subject created by: {subjectAuthor} -{" "}
{(authRating / authNoOfVotes).toFixed(1)}/5 Star user
{/* <br /> {subject.date} */}
</p>
</div>
<div className="subjectDescription">
<p className="description">{subject.description}</p>
</div>
<div className="subjectLinks">
Supporting Link: <br />
<a href={subject.links} target="blank">
{subject.links}
</a>
</div>
</div>
<div className="rightSubjectBody">
<div className="rate">
<p>
<b>Rate this subject</b>
</p>
<button
onClick={() => this.rateHandler(subject._id, 1, "subject")}
>
1
</button>
<button
onClick={() => this.rateHandler(subject._id, 2, "subject")}
>
2
</button>
<button
onClick={() => this.rateHandler(subject._id, 3, "subject")}
>
3
</button>
<button
onClick={() => this.rateHandler(subject._id, 4, "subject")}
>
4
</button>
<button
onClick={() => this.rateHandler(subject._id, 5, "subject")}
>
5
</button>
</div>
<div className="voting">
<p>
Do you think this subject question is false, mostly false,
half and half, mostly true or true, based on the evidence
provided and your own reseach in the area? Please vote below
and leave comments.
</p>
<div
className="voteButton"
onClick={() =>
this.voteHandler(subject._id, subject.false, "False")
}
>
FALSE
</div>
<div
className="voteButton"
onClick={() =>
this.voteHandler(
subject._id,
subject.mostlyFalse,
"mostlyFalse"
)
}
>
MOSTLY FALSE
</div>
<div
className="voteButton"
onClick={() =>
this.voteHandler(
subject._id,
subject.halfAndHalf,
"halfAndHalf"
)
}
>
HALF AND HALF
</div>
<br />
<div
className="voteButton"
onClick={() =>
this.voteHandler(
subject._id,
subject.mostlyTrue,
"mostlyTrue"
)
}
>
MOSTLY TRUE
</div>
<div
className="voteButton"
onClick={() =>
this.voteHandler(subject._id, subject.true, "True")
}
>
TRUE
</div>
</div>
</div>
<div className="subjectComments">
<p style={{ fontWeight: "bold" }}>Comments:</p>
{comments.map((comment, i) => {
return (
<div key={i} className="singleComment">
<p>
{comment.title} - Comment rating :{" "}
{(comment.rating / comment.noOfVotes).toFixed(1)}/5
<br />
{comment.comment}
<br />
Comment by : {comment.authName} - This user has a rating
of {(comment.rating / comment.noOfVotes).toFixed(1)}/5
STARS
</p>
<div className="rate">
Rate this comment :{" "}
<button
onClick={() =>
this.rateHandler(comment._id, 1, "comment")
}
>
1
</button>
<button
onClick={() =>
this.rateHandler(comment._id, 2, "comment")
}
>
2
</button>
<button
onClick={() =>
this.rateHandler(comment._id, 3, "comment")
}
>
3
</button>
<button
onClick={() =>
this.rateHandler(comment._id, 4, "comment")
}
>
4
</button>
<button
onClick={() =>
this.rateHandler(comment._id, 5, "comment")
}
>
5
</button>
</div>
</div>
);
})}
<br />
<a href="/addcomment">
<div className="buttonAddComment">ADD COMMENT</div>
</a>
</div>
</div>
</div>
);
});
return (
<div id="Subject">
<GoogleSearch />
{subjectItems}
</div>
);
}
}
Subject.propTypes = {
fetchLatestSubjects: PropTypes.func.isRequired,
fetchTopicSubjects: PropTypes.func.isRequired,
fetchTopicComments: PropTypes.func.isRequired,
fetchComments: PropTypes.func.isRequired,
fetchUsers: PropTypes.func.isRequired,
rateSubject: PropTypes.func.isRequired,
rateComment: PropTypes.func.isRequired,
rateUser: PropTypes.func.isRequired,
trueVote: PropTypes.func.isRequired,
falseVote: PropTypes.func.isRequired,
subjects: PropTypes.array.isRequired,
comments: PropTypes.array.isRequired,
users: PropTypes.array.isRequired,
newPost: PropTypes.object,
};
const mapStateToProps = (state) => ({
subjects: state.subjects.items,
newSubject: state.subjects.item,
comments: state.comments.items,
users: state.auth.users,
newComment: state.comments.item,
});
// export default Subject;
export default connect(mapStateToProps, {
fetchLatestSubjects,
fetchTopicSubjects,
fetchTopicComments,
fetchComments,
fetchUsers,
rateSubject, // rate subject
rateUser,
rateComment,
trueVote,
mostlyTrueVote,
falseVote,
mostlyFalseVote,
halfAndHalfVote,
})(Subject, Comment);
这就是我们在 React 测试库中的做法。您可以通过相应地替换实用函数将其转换为酶。
- 为需要渲染的组件提供 store。
it('renders with redux', () => {
render(<Provider store={store}>
<ReduxCode />
</Provider>);
//further code...
})