2010-07-07 32 views
4

这是我有点担心的一堂课。我的目标是单元测试地址列表:单元测试时使用反射或属性?

public class LabelPrinter 
{ 
    private readonly IEnumerable<Address> _addresses; 

    public LabelPrinter(IEnumerable<Address> addresses) 
    { 
     _addresses = addresses; 
    } 

    public Document Create() 
    { 
     // ... Generate PDF, etc ... 
    } 
} 

那么,什么是最好的:

  1. 使用反射来检查私有财产,或
  2. 由于原来的IEnumerable可以从外部反正修改,做一个公共getter并且测试它?

回答

0

特别是在学习单元测试时,通过简单的测试和更好的覆盖率,让关于保持领域私密性的担忧被超越。选项2.

7

一般来说,私人成员不应该进行单元测试,因为任何类使用它的私人成员应该以某种方式反映在对象的外部可测试行为中。换句话说,只要外部行为是应该的,谁在乎那里发生了什么。

单元测试私人成员还会将您的测试耦合到一个类的内部,使它们变得更脆弱。如果您以后决定使用更高效的集合,即使对象的行为没有改变,您的测试也会中断。您特别希望避免反射,因为按名称查找属性意味着如果属性名称发生更改,则测试会中断。

换句话说 - 如果您需要测试Address类,请从自己的单元测试中进行测试,而不是从LabelPrinter的测试中进行。如果您必须使用两种方法中的一种,请使用第二种方法,而不是反射。

+0

该地址只是一个数据容器。我想测试的是IEnumerable的长度,例如,不暴露给外部。 – ciscoheat 2010-07-08 12:27:40

+1

@ciscoheat - 通过测试IEnumerable的长度,你会获得什么?你不需要为.NET的赋值语句编写单元测试。 ('_addresses = addresses')。 – 2010-07-08 14:43:43

+0

我想知道查询是否返回了正确的地址列表,例如。 – ciscoheat 2010-07-08 21:37:58

1

你想在这里测试addresses列表?在上面提供的示例代码中,实际上很容易,因为您可以通过构造函数注入列表。因此,在您的测试,你可以访问列表本身,因此并不一定需要再次揭露它:

[Test] 
public void Test() 
{ 
    IEnumerable<Address> addresses = new List<Address>(); 
    LabelPrinter printer = new LabelPrinter(addresses); 

    ... // execute your test here 

    Assert.AreEqual(blah, addresses.get(0)); 
    // or any other assertion you want to make on the addresses list 
    // created up above. 
} 
0

测试Create,而不是制定者(这是有效的,你有什么在这里)。我发现测试setter/getters是有点浪费时间。 ESP。因为大多数情况下,制定者必须执行一些其他测试才能工作。它们大部分也太简单而不会失败。

因此,而不是验证LabelPrinter_addresses,它是Y,检查输出Create包括相关的详细信息。