嘲笑:如何避免孩子跟父母说话?
我正在尝试通过传递模拟所有者来测试对象。最初 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
的属性,该属性需要实现一个属性 >Transactions
,这是一个带有Count
的列表。
我只对测试 PartD
中的一种方法的一部分感兴趣,所以我对重新设计整个软件并不真正感兴趣,肯定会引入回归,所以我可以测试我的 2 分钟使固定。我花了 2 分钟进行修复,现在花了 6 个小时试图弄清楚如何测试它:
PartD partd = new PartD(mock);
partD.HomeAddress = "123 Maïn Street";
CheckEquals(partD.HomeAddress, "123 Main Street");
即使我愿意重新设计整个东西;将
TransactionCount
传递给每个子对象,每次它发生变化时,这似乎是一个可怕的设计。Validate
方法,3 个子级向下,需要知道是否有其他事务,这并不是系统中子级需要了解其父级信息的唯一情况。如果父对象将所有这些信息传递给所有子对象,无论他们是否需要它,都是一种浪费 - 并且容易在某个地方丢失更新。
此外,每次子子子对象进行新的内部检查时,它都必须重新设计其周围的所有对象 - 这样它们都能通过记录可能需要也可能不需要的信息。
如何避免孩子按要求与父母交谈,同时又不让父母给孩子他们不想要的东西?
编辑:我正在等待测试的更改是
if (Pos(homeAddress, "\r\n") > 0) ...
:
if (Pos("\r\n", homeAddress) > 0) ...
i'm trying to test an object by passing a mock owner. Originally PartD
would be passed a PartB1
as its owner:
PartD partD = new PartD(partB1);
Now i want to test a feature of PartD
by passing it a mock owner
:
PartD partD = new PartD(mockPartB1);
This works okay, except there are things PartD
does that depends on it knowing some statuses of some of its owners owners:
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");
}
...
}
This causes my mock object problems because the PartD
needs my mock to be of type PartB1
, and it needs to implement a property called PartA
, which needs to implement a property Transactions
, which is a list with a Count
.
i'm only interested in testing one part of one method in PartD
, so i'm not really interested in re-designing an entire piece of software, surely introducing regressions, so i can test my 2 minute fix. i spent 2 minutes making the fix, and have now lost 6 hours trying to figure out how to test it:
PartD partd = new PartD(mock);
partD.HomeAddress = "123 Maïn Street";
CheckEquals(partD.HomeAddress, "123 Main Street");
Even if i were willing to redesign the entire thing; passing down the
TransactionCount
to every child object, every time it changes seems like a horrible design. TheValidate
method, 3 children down, needing to know if there are other transactions isn't the only case in the system of a child needing to have information about its parents.If the parent objects passed down all this information down to all children, whether they needed it to not, is a waste - and prone to missing an update somewhere.
Also, each time a child-child-child object has a new internal check, it have to re-design all objects around it - so they can all pass down information that may or may not be needed.
How can i avoid children talking to their parents as required, while not having parents giving child objects they don't want?
Edit: The change i'm waiting to test is:
if (Pos(homeAddress, "\r\n") > 0) ...
to
if (Pos("\r\n", homeAddress) > 0) ...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为该方法可能确实需要重写(或者至少重构一下);但是,如果您可以控制
partB1
类,则可以进行一个快速更改,以便更轻松地测试,即向partB1 添加一个名为Is24Hour
的属性,该属性返回PartA.Transactions.Count > 1.
.然后你的模拟就可以为该特定属性返回 true 或 false。显然,这只在您拥有少量此类深层属性访问时才有帮助。
I think the method probably does need to be rewritten (or at least, refactored a bit); However, if you have control of the
partB1
class maybe a quick change that would make it easier to test would be to add a property to partB1 namedIs24Hour
that returnsPartA.Transactions.Count > 1
. Then your mock can just return true or false for that particular property.Obviously this only helps if you have a small number of these deep property accesses.