RhinoMock AssertWasCalled对同一个对象调用两次
本文关键字:两次 调用 AssertWasCalled 一个对象 RhinoMock | 更新日期: 2023-09-27 18:02:37
我有一个方法,它将对象添加到数据库中,处理该对象,然后在处理成功时更新数据库中的同一对象。处理是系统(支付)中非常关键的一部分,所以我想确保如果系统在处理过程中崩溃/停电,我们仍然有初始添加,然后我们可以再次处理。
public void CreateAndProcess(){
var myObj= new myObj
{
// Set up myObj here
};
db.Add(myObj);
db.SaveChanges();
// Process and update myObj here
db.Update(myObj);
db.SaveChanges();
}
然后我想对CreateAndProcess方法进行单元测试,以确保使用包含正确值的myObj调用Add和Update方法。
// addedObj and updatedObj are objects I define in my test that should match.
_store.AssertWasCalled(store => store.Add(Arg<myObj>.Matches(mo => Equal(mo, addedObj))),
option => option.Repeat.Once()); // Initial add to db
_store.AssertWasCalled(store => store.Update(Arg<myObj>.Matches(mo => Equal(mo, updatedObj))),
option => option.Repeat.Once()); // Update in db after processed
private static bool Equal(myObj s1, myObj s2)
{
// Used to match a subset of properties I care about
Assert.That(s1.myProp, Is.EqualTo(s2.myProp), "Unexpected argument");
return true;
}
问题是第一个AssertWasCalled使用对象的最终状态,在它被更新之后,而不是它在Add()函数被调用时的值。
如何测试myObj在最初添加到数据库时的状态?
谢谢,
Rhino Mock提供Do()
处理程序,以便在调用存根方法时访问存根方法的参数。
因此,可以为Add(MyObj)
方法编写一个自定义处理程序,该处理程序可以存储传递的myObj
参数的必要字段。然后可以对存储的字段运行断言。
下面是一个例子:
string actualMyPropOnAdd = null;
_store
.Stub(s => s.Add(Arg<MyObj>.Is.Anything))
.Do((Action<MyObj>)(myObj =>
{
// save the necessary properties to validate them later
actualMyPropOnAdd = myObj.myProp;
}));
// call CreateAndProcess() here
// validate saved properties:
Assert.That(actualMyPropOnAdd, Is.EqualTo(expectedMyPropOnAdd));
我还建议每个测试规则遵循一个asser,并编写另一个单独的测试来验证传递给Update()
方法的参数是正确的。