用虚拟方法嘲笑一个类将允许你验证方法。您也可以使用CallBase
同时调用实际方法(Update
)。
假设下面的代码(假设你发布更新不包含ref
参数,我已经移除斯普利特不必要REF):
public class Type
{
public string currency { get; set; }
public int OrderNo { get; set; }
}
public class BaseClass
{
// w.r.t ref, do you mean to reassign objList to the filtered lists?
public void SplitList(ref IList<Type> objList)
{
var SplitA = objList.Where(c => c.currency == "USD").ToList();
var SplitB = objList.Where(c => c.currency == "GBR").ToList();
if (SplitA.Count() > 0)
{
Update(SplitA);
}
if (SplitB.Count() > 0)
{
Update(SplitB);
}
}
public virtual IList<Type> Update(IList<Type> updateList)
{
int count = 0;
foreach (Type objType in updateList)
{
objType.OrderNo = count++;
}
return updateList;
}
}
这个单元测试表明,虚拟Update
方法可以验证以及被调用。如果您选择而不是以使用CallBase
,则需要调整单元测试,因为不会发生列表中元素的突变。
[Test]
public void TestSplitList()
{
var mock = new Mock<BaseClass>();
mock.CallBase = true; // This will ensure the actual Update also gets called
IList<Type> fakeTypes = new List<Type>
{
new Type {currency = "GBR"},
new Type {currency = "GBR", OrderNo = 100},
new Type {currency = "JPY", OrderNo = 55}
};
mock.Object.SplitList(ref fakeTypes);
mock.Verify(m => m.Update(It.IsAny<IList<Type>>()), Times.Exactly(1));
mock.Verify(m => m.Update(It.Is<IList<Type>>(x => x.Any(y => y.currency == "GBR")
&& x.Count == 2)), Times.Exactly(1));
mock.Verify(m => m.Update(It.Is<IList<Type>>(
x => x.Any(y => y.currency == "JPY"))), Times.Never);
Assert.AreEqual(3, fakeTypes.Count, "List itself must not have changed");
// These tests show the effect of the actual `Update` method
Assert.IsTrue(fakeTypes.Any(t => t.OrderNo == 0 && t.currency == "GBR"),
"GBR must be ordered");
Assert.IsTrue(fakeTypes.Any(t => t.OrderNo == 1 && t.currency == "GBR"),
"GBR must be ordered");
Assert.IsFalse(fakeTypes.Any(t => t.OrderNo == 100 && t.currency == "GBR"),
"GBR must be ordered");
Assert.IsTrue(fakeTypes.Any(t => t.OrderNo == 55 && t.currency == "JPY"),
"JPY must not be ordered");
}
注:在List
参数使用的ref
是在当前的代码实现不必要的。由于您直接变更列表中的对象,所有引用这些项目的集合都可以看到这些更改。此外,你并没有改变列表本身(只是其中的元素),所以你不需要使Update
参数ref
,也不要从Update
返回它。
显示我们的更新方法执行 –
公共虚拟更新(IList的 updateList) { \t诠释计数= 0; \t foreach(更新列表中的类型objType) \t { \t \t objType.OrderNo = count ++; \t} \t return updateList; }就像这样。 –
Anshul