【发布时间】:2019-02-21 01:49:51
【问题描述】:
我正在创建几个单元测试,我想验证是否使用我期望的参数调用方法。
所以给定这个非常简单的系统:
public class Employee
{
public bool IsEmployed { get; set; }
}
public class DataStore
{
public void UpdateEmployee(Employee obj)
{
// Save in DB
}
}
public interface IDataStore
{
void UpdateEmployee(Employee employee);
}
public Employee FireEmployee(IDataStore dataStore, Employee employee)
{
employee.IsEmployed = false;
dataStore.UpdateEmployee(employee);
return employee;
}
我想验证 Employee.IsEmployed 属性设置为 false 时是否调用了 DataStore.UpdateEmployee() 方法。所以这里有两个我认为应该完成同样事情的测试用例。
[Test]
public void TestViaVerify()
{
//Arrange
Mock<IDataStore> dataStore = new Mock<IDataStore>();
var robert = new Employee { IsEmployed = true };
//Act
FireEmployee(dataStore.Object, robert);
//Assert
dataStore.Verify(x => x.UpdateEmployee(It.Is<Employee>(e => e.IsEmployed == false)), Times.Once);
}
[Test]
public void TestViaSetupVerifyAll()
{
//Arrange
Mock<IDataStore> dataStore = new Mock<IDataStore>();
dataStore.Setup(x => x.UpdateEmployee(It.Is<Employee>(e => e.IsEmployed == false)));
var robert = new Employee { IsEmployed = true };
//Act
FireEmployee(dataStore.Object, robert);
//Assert
dataStore.VerifyAll();
}
鉴于系统的当前代码,两个测试都按预期通过。
现在说另一个开发人员意外地在DataStore.UpdateEmployee() 方法之后移动了Employee.IsEmployed = false; 的设置。现在在这种情况下,我希望我的测试失败,因为该员工不会在数据库中被标记为失业。
public Employee FireEmployee(IDataStore dataStore, Employee employee)
{
dataStore.UpdateEmployee(employee);
employee.IsEmployed = false;
return employee;
}
现在当我运行测试时:
TestViaVerify 通过
TestViaSetupVerifyAll 失败
我原以为它们都会失败,但对于 TestViaVerify() 方法来说,该方法中的 lambda 在测试结束时执行,其中 Employee.IsEmployed 已经设置为 false。
有没有办法只使用验证方法来完成我想要的?并且不必进行设置...VerifyAll?如果没有,我将使用TestViaVerifyAll() 方法。
【问题讨论】:
-
这似乎是
moq的问题。当您通过引用更改已捕获的对象时。您能否在调用dataStore.UpdateEmployee之前尝试制作副本。我的假设是Verify也会失败。
标签: c# unit-testing nunit moq assert