我正在创建几个单元测试,希望验证某个方法是否被调用,并且参数的属性符合我的期望。
因此,考虑到这个非常简单的系统:
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();
}
根据系统当前的代码,两个测试都如预期一样通过了。
现在假设另一个开发人员不小心把 Employee.IsEmployed = false;
的设置移到了 DataStore.UpdateEmployee()
方法之后。在这种情况下,我希望我的测试会失败,因为该雇员将不会被标记为失业状态。
public Employee FireEmployee(IDataStore dataStore, Employee employee)
{
dataStore.UpdateEmployee(employee);
employee.IsEmployed = false;
return employee;
}
现在当我运行测试时:
TestViaVerify方法通过。
TestViaSetupVerifyAll方法失败。
我本来期望它们都会失败,但看起来在TestViaVerify()方法中,方法中的lambda表达式是在测试结束时执行的,此时Employee.IsEmployed已经被设置为false。
有没有一种只使用Verify方法就可以实现我的目标的方法?而不必使用Setup...VerifyAll方法?如果没有,我将采用TestViaVerifyAll()方法。
moq
的问题。因为您正在通过引用更改已捕获的对象。在调用dataStore.UpdateEmployee
之前,您可以尝试复制一份副本。我的假设是Verify
也会失败。 - Johnny