Javascript 如何在React中同步测试?

Javascript 如何在React中同步测试?,javascript,reactjs,jestjs,Javascript,Reactjs,Jestjs,我有注释列表组件,它显示一个包含所有注释的列表。每个评论都有一个“回复”按钮,打开AddComment组件(该组件允许我向评论添加回复)。为了显示每个注释的AddComment组件,我使用了一个状态数组 AddComment组件包含用于输入的文本区域、取消按钮和提交按钮。当我点击提交按钮并成功添加回复时,AddComment组件关闭。如果输入是空的,我单击submit按钮,组件不会关闭,因为输入不能为空才能成功提交。 我想测试此功能,以便在发布回复后验证AddComment组件是否消失 问题是,

我有注释列表组件,它显示一个包含所有注释的列表。每个评论都有一个“回复”按钮,打开AddComment组件(该组件允许我向评论添加回复)。为了显示每个注释的AddComment组件,我使用了一个状态数组

AddComment组件包含用于输入的文本区域、取消按钮和提交按钮。当我点击提交按钮并成功添加回复时,AddComment组件关闭。如果输入是空的,我单击submit按钮,组件不会关闭,因为输入不能为空才能成功提交。 我想测试此功能,以便在发布回复后验证AddComment组件是否消失

问题是,在测试中,当我单击submit按钮时,我的添加注释组件并没有消失。我注意到注释添加成功,但是注释的AddComment组件的状态没有改变。当我点击submit按钮时,输入被提交,但是改变状态的函数从未被调用。我认为问题可能是操作不同步

我尝试使用wait act呈现CommentsList组件,以确保测试运行更接近React在浏览器中的工作方式,但我的AddComment组件仍然没有消失

这是我的CommentsList组件

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();
});