在处理用户输入时给定时间

本文关键字:定时间 输入 处理 用户 | 更新日期: 2023-09-27 18:34:07

我正在寻找一些关于安排/行动/断言的澄清,我正在我的开发过程中以Given-When-Then的形式实现它。我试图坚持这个概念,但我发现在某些事件(特别是用户输入(期间,我必须将"Act"操作重新考虑为"安排"操作,以便在单元测试中正确捕获它。我在这里使用 Moq 作为我的模拟框架。

例如:在我的项目中,代码的焦点是用户提供的图像。存在一项功能,用户可以在其中选择图像,但如果图像已存在,它将查询用户是否要替换活动图像,或取消操作并保留活动图像。我觉得编写此特定场景的正确方法是:

给定一个已经存在
图像的工作区当用户请求新图像
并且用户选择替换活动图像
然后程序应该替换图像

测试方面,它看起来像这样:

mockModel.SetupProperty(m => m.Image, new Bitmap(100, 100));  // Given
mockView.Raise(v => v.UserRequestsNewImage += null);          // When
mockMBox.Setup(mb => mb.ViewResult).Returns(ViewResult.OK);   // And
mockView.Verify(v => v.OpenAddImageFileDialog(), Times.Once); // Then

代码方面,在我的演示器中,它看起来像这样:

private void view_UserRequestsNewImage()
{
  if (model.Image != null)
  {
    mbox.ShowDialog();
    if (mbox.ViewResult == ViewResult.Cancel)
      return;
  }
  view.OpenAddImageFileDialog();
}

但这会失败,因为消息框的Setup发生在调用视图的Raise之后。因此,我需要在它之前移动Setup(无论如何,使用 Setup 会让它感觉像"排列"设置(:

给定一个已经存在
图像的工作区并且用户选择替换活动图像
当用户请求新图像
然后程序应该替换图像

但是现在,我的场景感觉不正常,并且无法正确流动。我觉得用户选择替换图像(Setup(,因为它发生在用户选择添加新图像(Raise(之后,应该是 Act 步骤的一部分,但为了让它正确模拟,我需要把它放在排列步骤中。

我在这里使用嘲笑框架是错误的吗?有没有更好的方法可以做到这一点?还是我不切实际地担心用户输入步骤应该在给定时间设置中的位置?

提前谢谢。

在处理用户输入时给定时间

"当用户请求新图像时",用户必须选择替换当前图像。

所以你可以把"给定,何时,然后"重写为:

  • 给定一个已经存在图像的工作区
  • 当用户选择替换活动映像时
  • 然后程序应该替换图像
即省略"何时",该">

声明"用户请求新图像",因为他们在替换当前图像时无论如何都必须这样做。

此外,我会放弃注释(代码气味,尽管它们并不多!(并将这些测试步骤放入小方法中,如下所示:

void GivenImageAlreadyPresent()
{
 mockModel.SetupProperty(m => m.Image, new Bitmap(100, 100));  
}
void WhenActiveImageReplaced()
{
 mockMBox.Setup(mb => mb.ViewResult).Returns(ViewResult.OK);   
 mockView.Raise(v => v.UserRequestsNewImage += null);          
}
void ThenImageShouldBeReplaced()
{
 mockView.Verify(v => v.OpenAddImageFileDialog(), Times.Once);
}
void Test()
{
 GivenImageAlreadyPresent();
 WhenActiveImageReplaced();
 ThenImageShouldBeReplaced();
}

这使得实际测试读取得更好(即它现在自我记录(,并且可以在需要时重用这些步骤。