我必须修复,第二次删除了代码行。所以我决定为此编写一个单元测试。
构造函数中的一个类设置了我想要测试的属性。该属性恰好受到保护,因此我无法在单元测试中访问它。
[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);
现在我的团队有一个争论,我应该只测试公共接口和其他事情,这是一个快速而又脏的黑客。
但是,单元测试的目的之一是保护代码库免受不必要的更改吗?如果这完全错了还应该做什么?
答案 0 :(得分:3)
受保护的变量是接口的一部分。它是任何子类可以使用的接口的一部分。这个问题对受保护变量有很好的总结。 Is it good practice to make member variables protected?
如果允许派生类访问其基类的数据,那么派生类需要注意不要使基类的数据的不变量无效。这会将封装抛出窗口,这是错误的。 (那么吸气鬼和二传手,BTW。)
在回答你的问题时,如果子类不应该访问该变量,那么它应该是private
。否则你的单元测试是有效的,可以说它应该早先实现!
答案 1 :(得分:2)
在阅读Roy Osherove's 'Art of Unit Testing'之后,我对此的看法是,测试+可维护性是良好代码的主要用例。因此,我认为扩展类型以帮助测试的情况非常有效。
当然,如果您可以设计一种不需要它的类型,那么它就是好的,但可维护性和可测试性是至关重要的。
通常说泄漏抽象是一个糟糕的选择,但我发现在大多数情况下这是因为没有考虑这两个主要用例。抽象应该对所有用户都有好处:功能&测试&维护。
答案 2 :(得分:1)
您应该完全删除该字段,直到实际需要通过外部测试。如果没有失败的外部行为,则不需要该字段。
由于该字段受到保护,我假设您创建了该字段以从中获取某些内容。此派生类是否需要受保护的字段才能通过任何其测试?在那种情况下,你被覆盖了。