我正在尝试通过传递模拟所有者来测试对象。最初PartD
将作为所有者传递PartB1
:
PartD partD = new PartD(partB1);
现在我要通过传递模拟PartD
来测试owner
的功能:
PartD partD = new PartD(mockPartB1);
这样做没问题,但有些事情PartD
确实取决于它知道某些业主的某些状态:
Boolean PartD.Validate()
{
//Some fields are not required if the PartA has more than one transaction
Boolean is24Hour = (this.PartB1.PartA.Transactions.Count > 1);
if (this.Firstname == "")
{
if (!is24Hour)
LogError("First name is empty");
else
LogWarning("First name is empty, but requires reasonable efforts");
}
...
}
这会导致我的模拟对象出现问题,因为PartD
需要我的模型为PartB1
类型,并且需要实现一个名为PartA
的属性,它需要实现一个属性{ {1}},这是一个Transactions
的列表。
我只对测试Count
中一种方法的一部分感兴趣,所以我真的不想重新设计整个软件,肯定会引入回归,所以我可以测试我的2分钟固定。我花了2分钟来修复,现在已经失去了6个小时试图弄清楚如何测试它:
PartD
即使我愿意重新设计整个事物;将
PartD partd = new PartD(mock); partD.HomeAddress = "123 Maïn Street"; CheckEquals(partD.HomeAddress, "123 Main Street");
传递给每个子对象,每次它变化都看起来像一个可怕的设计。TransactionCount
方法,3个孩子,需要知道是否有其他交易,并不是孩子需要获得有关其父母信息的系统的唯一情况。如果父对象将所有这些信息传递给所有孩子,无论他们是否需要它,都是浪费 - 而且很容易在某处丢失更新。
此外,每次儿童 - 儿童 - 儿童对象都有新的 内部 检查时,它必须重新设计它周围的所有对象 - 所以它们都可以通过可能需要或可能不需要的信息。
我如何避免孩子根据需要与父母交谈,而不让父母给孩子不想要的物品?
编辑:我正在等待测试的更改是:
Validate
到
if (Pos(homeAddress, "\r\n") > 0) ...
答案 0 :(得分:1)
我认为该方法可能确实需要重写(或者至少重构一下);但是,如果您可以控制partB1
类,那么可以快速更改,以便更容易测试,即将属性添加到返回Is24Hour
的名为PartA.Transactions.Count > 1
的partB1。那么你的模拟只能为该特定属性返回true或false。
显然,只有少数这些深层属性访问才有用。