MOQ C# 中的设置和返回是什么?

问题描述

我阅读了一些关于 Moq C# 包的教程,但我仍然无法真正理解 Setup 中的 ReturnsMoq

示例,

mock.Setup(p => p.GetEmployeebyId(1)).ReturnsAsync("JK"); 

示例 2,

mock.Setup(x => x.Save(It.IsAny<DeskBooking>())).Callback<DeskBooking>(
deskBooking =>
{
savedDeskBooking = deskBooking;
});

)

解决方法

在示例 1 中

mock.Setup(p => p.GetEmployeebyId(1)).ReturnsAsync("JK"); 

设置您的模拟,因此当以 1 作为参数调用 GetEmployeebyId 时,模拟将返回“JK”。

在示例 2 中

mock.Setup(x => x.Save(It.IsAny<DeskBooking>())).Callback<DeskBooking>(
deskBooking =>
{
savedDeskBooking = deskBooking;
});

当使用 Save 类型的任何参数调用 DeskBooking 方法时,lambda 函数会将参数保存在 savedDeskBooking 变量中。然后您可以测试您是否保存了您期望的 DeskBooking

,

TL;DR:Setup = 什么时候,Returns = 什么

每当您编写单元测试时,您都希望确保给定的功能按预期工作。但大多数情况下,功能依赖于其他一些组件/环境/外部源/任何东西。

为了使您的测试具有针对性和可重播性,我们需要使用测试替身。这些将在测试期间替换您的依赖项。我们可以这样分类测试替身:

  • Dummy:返回虚假数据的简单代码
  • 假的:可行的替代方案,可以走捷径
  • 存根:带有预定义数据的自定义逻辑
  • Mock:具有期望的自定义逻辑(交互式存根)
  • Shim:自定义逻辑在运行时(用委托替换静态)
  • 间谍拦截器记录通话

所以,无论何时你想创建一个模拟,你都必须告诉组件在什么情况下应该如何表现。换句话说,使用特定输入调用该函数时,什么应该是预期的输出。

在 Moq 的情况下,您可以使用 Setup 来定义时间。和 Returns 来指定什么。

这是一个简单的例子。假设您有以下功能:

private IService service;
string MyMethod()
{
   int number = service.GetNextNumber();
   if(number % 2 == 0)
   {
       return "even";
   }
   else
   {
       return "odd";
   }
}

然后你可以编写以下测试用例:

public void GivenAnEvenNumber_WhenICallMyMethod_ThenItShouldReturnEven
{
   //Arrange
   var serviceMock = new Mock<IService>();
   serviceMock
      .Setup(svc => svc.GetNextNumber())
      .Returns(2);
   ...

   //Act
   var result = SUT.MyMethod();

   //Assert
   Assert.Equal("even",result);
}

public void GivenAnOddNumber_WhenICallMyMethod_ThenItShouldReturnOdd
{
   //Arrange
   var serviceMock = new Mock<IService>();
   serviceMock
      .Setup(svc => svc.GetNextNumber())
      .Returns(1);
   ...

   //Act
   var result = SUT.MyMethod();

   //Assert
   Assert.Equal("odd",result);
}

因此,如您所见,我们使用 SetupReturns 来指导每个测试用例中的控制流。


您的第二个示例可以被视为间谍,因为您正在记录输入以供后续评估使用。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...