我有一个方法,它将对象添加到数据库,处理该对象,然后在处理成功时更新数据库中的同一对象。处理是系统(支付)的一个非常关键的部分,所以我想确保如果系统在处理过程中崩溃/掉电,我们仍然有初始添加,然后我们可以再次处理。
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的状态?
谢谢,
答案 0 :(得分:1)
Rhino Mock在调用stubbed方法时提供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));
另外,我建议关注one asser per test rule并编写另一个单独的测试来验证传递给Update()
方法的参数是否正确。