扩展类以便对其受保护的属性进行单元测试是错误的吗?

时间:2013-06-07 19:24:42

标签: unit-testing

我必须修复,第二次删除了代码行。所以我决定为此编写一个单元测试。

构造函数中的一个类设置了我想要测试的属性。该属性恰好受到保护,因此我无法在单元测试中访问它。

 [Test]
 public void Constructor_WhenCalled_ThenSomePropertyIsPopulated()
 {
     var vm= new SomeViewModel();
     //line below doesn't compile as SomeProperty is protected
     Assert.IsNotNull(vm.SomeProperty);

所以我在单元测试文件中决定扩展该类(它没有密封)并将受保护的属性公开为公共getter:

public class SomeViewModelExtended : SomeViewModel
{
    public SomeViewModelExtended() : base() { }

    public new object SomeProperty
    {
        get { return base.SomeProperty; }
    }
}

 //now I can test
 [Test]
 public void Constructor_WhenCalled_ThenSomePropertyIsPopulated()
 {
     var vm= new SomeViewModelExtended();
     Assert.IsNotNull(vm.SomeProperty);

现在我的团队有一个争论,我应该只测试公共接口和其他事情,这是一个快速而又脏的黑客。

但是,单元测试的目的之一是保护代码库免受不必要的更改吗?如果这完全错了还应该做什么?

3 个答案:

答案 0 :(得分:3)

受保护的变量接口的一部分。它是任何子类可以使用的接口的一部分。这个问题对受保护变量有很好的总结。 Is it good practice to make member variables protected?

  

如果允许派生类访问其基类的数据,那么派生类需要注意不要使基类的数据的不变量无效。这会将封装抛出窗口,这是错误的。 (那么吸气鬼和二传手,BTW。)

在回答你的问题时,如果子类不应该访问该变量,那么它应该是private。否则你的单元测试是有效的,可以说它应该早先实现!

答案 1 :(得分:2)

在阅读Roy Osherove's 'Art of Unit Testing'之后,我对此的看法是,测试+可维护性是良好代码的主要用例。因此,我认为扩展类型以帮助测试的情况非常有效。

当然,如果您可以设计一种不需要它的类型,那么它就是好的,但可维护性和可测试性是至关重要的。

通常说泄漏抽象是一个糟糕的选择,但我发现在大多数情况下这是因为没有考虑这两个主要用例。抽象应该对所有用户都有好处:功能&测试&维护。

答案 2 :(得分:1)

您应该完全删除该字段,直到实际需要通过外部测试。如果没有失败的外部行为,则不需要该字段。

由于该字段受到保护,我假设您创建了该字段以从中获取某些内容。此派生类是否需要受保护的字段才能通过任何测试?在那种情况下,你被覆盖了。