Javascript 如何在React中同步测试?
我有注释列表组件,它显示一个包含所有注释的列表。每个评论都有一个“回复”按钮,打开AddComment组件(该组件允许我向评论添加回复)。为了显示每个注释的AddComment组件,我使用了一个状态数组 AddComment组件包含用于输入的文本区域、取消按钮和提交按钮。当我点击提交按钮并成功添加回复时,AddComment组件关闭。如果输入是空的,我单击submit按钮,组件不会关闭,因为输入不能为空才能成功提交。 我想测试此功能,以便在发布回复后验证AddComment组件是否消失 问题是,在测试中,当我单击submit按钮时,我的添加注释组件并没有消失。我注意到注释添加成功,但是注释的AddComment组件的状态没有改变。当我点击submit按钮时,输入被提交,但是改变状态的函数从未被调用。我认为问题可能是操作不同步 我尝试使用wait act呈现CommentsList组件,以确保测试运行更接近React在浏览器中的工作方式,但我的AddComment组件仍然没有消失 这是我的CommentsList组件Javascript 如何在React中同步测试?,javascript,reactjs,jestjs,Javascript,Reactjs,Jestjs,我有注释列表组件,它显示一个包含所有注释的列表。每个评论都有一个“回复”按钮,打开AddComment组件(该组件允许我向评论添加回复)。为了显示每个注释的AddComment组件,我使用了一个状态数组 AddComment组件包含用于输入的文本区域、取消按钮和提交按钮。当我点击提交按钮并成功添加回复时,AddComment组件关闭。如果输入是空的,我单击submit按钮,组件不会关闭,因为输入不能为空才能成功提交。 我想测试此功能,以便在发布回复后验证AddComment组件是否消失 问题是,
function CommentsList(props) {
const { t } = useTranslation();
const [hasReplyCommentBox, setHasReplyCommentBox] = useState([]);
function toggleHasReplyComment(commentIndex) {
var auxState = { ...hasReplyCommentBox };
auxState[commentIndex] = auxState[commentIndex] ? 0 : 1;
setHasReplyCommentBox(auxState);
}
function replyToCommentButton(commentIndex) {
return [
<span
id={"replyButton-" + commentIndex}
onClick={() => toggleHasReplyComment(commentIndex)}>
{t('Reply to')}
</span>
];
}
function commentReplyBox(commentIndex, parentCommentId) {
return hasReplyCommentBox[commentIndex]
?
<AddComment
id={props.codeId}
parentCommentId={parentCommentId}
commentIndex={commentIndex}
toggleHasReplyComment={toggleHasReplyComment}
updateComments={props.updateComments}
/>
:
null
}
return (
<Layout>
<Layout>
<List
itemLayout="horizontal"
dataSource={props.comments}
renderItem={(comment, commentIndex) => (
<List.Item>
<CommentCard
userId={comment.user_id}
datePosted={comment.date_posted}
body={comment.body}
actions={replyToCommentButton(commentIndex)}
children={commentReplyBox(commentIndex, comment.id)}
/>
</List.Item>
)}
/>
<AddComment
id={props.codeId}
updateComments={props.updateComments}
/>
</Layout>
</Layout>
);
}
function AddComment(props) {
const { t } = useTranslation();
const { TextArea } = Input;
const [form] = Form.useForm();
const [comment, setComment] = useState();
const [onCommentAddSuccess, setOnCommentAddSuccess] = useState(0);
const buttonStyle = {
float: 'right'
};
function onCommentChange(newComment) {
setComment(newComment.target.value);
}
function updateOnCommentAddSuccess(onCommentAddSuccess) {
setOnCommentAddSuccess(onCommentAddSuccess + 1);
}
function resetCommentInput() {
setComment('');
}
function onFormReset() {
form.resetFields();
}
function toggleHasReplyCommentOnPost(parentCommentId, commentIndex) {
if (parentCommentId !== undefined) {
console.log('comentariu adaugat cu succes');
props.toggleHasReplyComment(commentIndex);
}
}
function submitComment() {
let request = {
body: comment,
code_id: props.id,
parent_comment_id: props.parentCommentId
};
fetch('/api/comment/add',
{
method: 'POST',
body: JSON.stringify(request)
}
).then(response => response.json())
.then(data => {
if (data.success === 1) {
updateOnCommentAddSuccess(onCommentAddSuccess);
props.updateComments(onCommentAddSuccess);
resetCommentInput();
toggleHasReplyCommentOnPost(props.parentCommentId, props.commentIndex);
}
});
}
return (
<>
<Form form={form} name="comment" className="comment-form"
onFinish={submitComment}>
<Form.Item name="body" label={t('Comment')}>
<TextArea placeholder={t('Leave a comment')}
onChange={onCommentChange}
id={"parent-comment-" + props.parentCommentId} />
</Form.Item>
<Form.Item style={buttonStyle}>
<Space>
{props.parentCommentId
?
<Button id={"cancelAddReplyComment-" + props.parentCommentId}
type="secondary" className = "comment-form-button"
onClick={
() => props.toggleHasReplyComment(props.commentIndex)
}>
{t('Cancel')}
</Button>
:
null
}
<Button type="primary" htmlType="submit"
className = "comment-form-button"
id={"post-comment-button-" + props.parentCommentId}
onClick={onFormReset}>
{t('Post')}
</Button>
</Space>
</Form.Item>
</Form>
</>
);
}
函数注释列表(道具){
const{t}=useTranslation();
const[hasReplyCommentBox,setHasReplyCommentBox]=useState([]);
函数切换HasReplyComment(commentIndex){
var auxState={…hasReplyCommentBox};
auxState[commentIndex]=auxState[commentIndex]?0:1;
setHasReplyCommentBox(auxState);
}
函数replyToCommentButton(commentIndex){
返回[
toggleHasReplyComment(commentIndex)}>
{t('Reply to')}
];
}
函数commentReplyBox(commentIndex,parentCommentId){
return hasReplyCommentBox[commentIndex]
?
:
无效的
}
返回(
(
)}
/>
);
}
这是我的AddComment组件
function CommentsList(props) {
const { t } = useTranslation();
const [hasReplyCommentBox, setHasReplyCommentBox] = useState([]);
function toggleHasReplyComment(commentIndex) {
var auxState = { ...hasReplyCommentBox };
auxState[commentIndex] = auxState[commentIndex] ? 0 : 1;
setHasReplyCommentBox(auxState);
}
function replyToCommentButton(commentIndex) {
return [
<span
id={"replyButton-" + commentIndex}
onClick={() => toggleHasReplyComment(commentIndex)}>
{t('Reply to')}
</span>
];
}
function commentReplyBox(commentIndex, parentCommentId) {
return hasReplyCommentBox[commentIndex]
?
<AddComment
id={props.codeId}
parentCommentId={parentCommentId}
commentIndex={commentIndex}
toggleHasReplyComment={toggleHasReplyComment}
updateComments={props.updateComments}
/>
:
null
}
return (
<Layout>
<Layout>
<List
itemLayout="horizontal"
dataSource={props.comments}
renderItem={(comment, commentIndex) => (
<List.Item>
<CommentCard
userId={comment.user_id}
datePosted={comment.date_posted}
body={comment.body}
actions={replyToCommentButton(commentIndex)}
children={commentReplyBox(commentIndex, comment.id)}
/>
</List.Item>
)}
/>
<AddComment
id={props.codeId}
updateComments={props.updateComments}
/>
</Layout>
</Layout>
);
}
function AddComment(props) {
const { t } = useTranslation();
const { TextArea } = Input;
const [form] = Form.useForm();
const [comment, setComment] = useState();
const [onCommentAddSuccess, setOnCommentAddSuccess] = useState(0);
const buttonStyle = {
float: 'right'
};
function onCommentChange(newComment) {
setComment(newComment.target.value);
}
function updateOnCommentAddSuccess(onCommentAddSuccess) {
setOnCommentAddSuccess(onCommentAddSuccess + 1);
}
function resetCommentInput() {
setComment('');
}
function onFormReset() {
form.resetFields();
}
function toggleHasReplyCommentOnPost(parentCommentId, commentIndex) {
if (parentCommentId !== undefined) {
console.log('comentariu adaugat cu succes');
props.toggleHasReplyComment(commentIndex);
}
}
function submitComment() {
let request = {
body: comment,
code_id: props.id,
parent_comment_id: props.parentCommentId
};
fetch('/api/comment/add',
{
method: 'POST',
body: JSON.stringify(request)
}
).then(response => response.json())
.then(data => {
if (data.success === 1) {
updateOnCommentAddSuccess(onCommentAddSuccess);
props.updateComments(onCommentAddSuccess);
resetCommentInput();
toggleHasReplyCommentOnPost(props.parentCommentId, props.commentIndex);
}
});
}
return (
<>
<Form form={form} name="comment" className="comment-form"
onFinish={submitComment}>
<Form.Item name="body" label={t('Comment')}>
<TextArea placeholder={t('Leave a comment')}
onChange={onCommentChange}
id={"parent-comment-" + props.parentCommentId} />
</Form.Item>
<Form.Item style={buttonStyle}>
<Space>
{props.parentCommentId
?
<Button id={"cancelAddReplyComment-" + props.parentCommentId}
type="secondary" className = "comment-form-button"
onClick={
() => props.toggleHasReplyComment(props.commentIndex)
}>
{t('Cancel')}
</Button>
:
null
}
<Button type="primary" htmlType="submit"
className = "comment-form-button"
id={"post-comment-button-" + props.parentCommentId}
onClick={onFormReset}>
{t('Post')}
</Button>
</Space>
</Form.Item>
</Form>
</>
);
}
函数AddComment(道具){
const{t}=useTranslation();
const{TextArea}=输入;
const[form]=form.useForm();
const[comment,setComment]=useState();
const[oncommentadsuccess,setoncommentadsuccess]=useState(0);
常量按钮样式={
浮动:“对”
};
更改建议的功能(新成员){
setComment(newComment.target.value);
}
函数updateOnCommentAddSuccess(onCommentAddSuccess){
setOnCommentAddSuccess(onCommentAddSuccess+1);
}
函数resetCommentInput(){
setComment(“”);
}
函数onFormReset(){
form.resetFields();
}
函数切换HasReplyCommentOnPost(parentCommentId,commentIndex){
if(parentCommentId!==未定义){
console.log(“comentariu adaugat cu succes”);
props.toggleHasReplyComment(commentIndex);
}
}
函数submitComment(){
让请求={
正文:评论,
代码_id:props.id,
父注释id:props.parentCommentId
};
获取('/api/comment/add',
{
方法:“POST”,
正文:JSON.stringify(请求)
}
).then(response=>response.json())
。然后(数据=>{
如果(data.success==1){
updateOnCommentAddSuccess(onCommentAddSuccess);
道具更新建议(onCommentAddSuccess);
resetCommentInput();
切换HasReplyCommentOnPost(props.parentCommentId,props.commentIndex);
}
});
}
返回(
{props.parentCommentId
?
props.toggleHasReplyComment(props.commentIndex)
}>
{t('Cancel')}
:
无效的
}
{t('Post')}
);
}
下面是我的测试结果
test ('Toggle displaying add reply to comments', async () => {
const comments = [
{
id: 'ID-1',
user_id: 'USER-ID-1',
date_posted: '2020-01-01 01:00:00',
body: 'First comment'
}
];
await act(async () => {
Promise.resolve(render(
<CommentsList comments={comments} />, container
));
});
// Open AddComment component
const replyButton = container.querySelector("#replyButton-0");
await fireEvent.click(replyButton);
// Insert input in the text area
const userInput = container.querySelector("#parent-comment-ID-1");
await userEvent.type((userInput), 'reply');
// Submit the input
const postButton = container.querySelector("#post-comment-button-ID-1");
await fireEvent.click(postButton);
// Check if the AddComment component is closed
expect(container.querySelector("#cancelAddReplyComment-ID-1")).toBeFalsy();
});
test('Toggle displaying add reply to comments',async()=>{
常量注释=[
{
id:'id-1',
用户id:'user-id-1',
发布日期:“2020-01-01 01:00:00”,
正文:“第一条评论”
}
];
等待动作(异步()=>{
承诺,决心(
,货柜
));
});
//打开AddComment组件
const replyButton=container.querySelector(“replyButton-0”);
等待fireEvent。单击(replyButton);
//在文本区域中插入输入
const userInput=container.querySelector(#parent-comment-ID-1”);
wait userEvent.type((userInput),'reply');
//提交输入
const postButton=container.querySelector(“post-comment-button-ID-1”);
等待fireEvent。单击(postButton);
//检查AddComment组件是否已关闭
expect(container.querySelector(#cancelAddReplyComment-ID-1”).toBeFalsy();
});