0

我正在尝试通过传递一个模拟所有者来测试一个对象。最初PartDPartB1作为其所有者传递 a :

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给每个子对象,每次更改似乎都是一个可怕的设计。方法,Validate3 个孩子下来,需要知道是否有其他交易不是孩子需要知道其父母信息的系统中的唯一情况。

如果父对象将所有这些信息传递给所有子对象,无论他们是否需要它,都是一种浪费——并且容易在某处错过更新。

此外,每次子-子-子对象进行新的内部检查时,它都必须重新设计它周围的所有对象——因此它们都可以传递可能需要或不需要的信息。

我怎样才能避免孩子按要求与父母交谈,同时又不让父母给孩子他们不想要的东西?


编辑:我正在等待测试的变化是:

if (Pos(homeAddress, "\r\n") > 0) ...

if (Pos("\r\n", homeAddress) > 0) ...
4

1 回答 1

1

我认为该方法可能确实需要重写(或至少重构一下);但是,如果您可以控制partB1该类,则可能使测试更容易的快速更改是向 partB1 添加一个名为Is24Hour返回的属性PartA.Transactions.Count > 1。然后,您的模拟可以只为该特定属性返回 true 或 false。

显然,这仅在您拥有少量这些深度属性访问时才有帮助。

于 2010-10-21T18:52:41.947 回答