简体   繁体   English

受保护的方法是否应该进行单元测试? 如何避免重复测试?

[英]Should protected methods be unit-tested? How to avoid repetitive testing?

Using C# 使用C#

I know this has been asked before and a lot of people will answer no, only test public methods, not implementation details. 我知道这已经被问过了,很多人会回答“不”,只测试公共方法,而不是实现细节。 Others will say yes, if it has some important logic. 如果它有一些重要的逻辑,其他人会说是的。 Although you might then consider breaking it off into its own class. 尽管您可能随后考虑将其分解为自己的类。

One issue I haven't seen addressed is having to repeat testing public methods that call protected methods in inherited classes. 我尚未看到的一个问题是必须重复测试在继承的类中调用受保护方法的公共方法。 If I test the protected method in the base class, surely I don't have to retest it in base classes. 如果我在基类中测试了受保护的方法,那么肯定不必在基类中重新测试它。 Or should I copy and paste the tests to multiple classes? 还是应该将测试复制并粘贴到多个类?

You definitely should test protected methods. 您绝对应该测试受保护的方法。 From a testing standpoint, a "protected" method still is part of the public interface, even though the "public" is limited to those classes that derive from your class. 从测试的角度来看,即使“公共”仅限于从您的类派生的类,“受保护”方法仍是公共接口的一部分。 Because code that you do not control can reference those methods, you must ensure that they function as defined. 由于您无法控制的代码可以引用这些方法,因此必须确保它们按定义运行。

As for repetitive testing, I don't have a definitive answer. 至于重复测试,我没有明确的答案。 If given: 如果给出:

public class A
{
    protected virtual void Foo() {}
}

public class B:A
{

}

The question is whether you write a test for B.Foo . 问题是您是否为B.Foo编写测试。 On one hand I would say no, because B doesn't provide an explicit implementation of Foo , and so its behavior can't possibly be different than the behavior of A.Foo , and we can assume that you've already tested A.Foo . 一方面,我会说不,因为B没有提供Foo的显式实现,因此它的行为与A.Foo的行为不可能不同,我们可以假设您已经测试过A.Foo

On the other hand, A.Foo could depend on some other protected fields or properties that B could modify, or on a private callback that B provides in a constructor or initialization function. 另一方面, A.Foo可能依赖于B可以修改的某些其他protected字段或属性,或者取决于B在构造函数或初始化函数中提供的私有回调。 In that case, then you absolutely must test B.Foo because its behavior could be different than A.Foo , even though B doesn't override A.Foo . 在那种情况下,您绝对必须测试B.Foo因为它的行为可能A.Foo不同,即使B不会覆盖A.Foo

Obviously, if B overrides Foo , then you have to write a test for B.Foo . 显然,如果B覆盖Foo ,那么您必须为B.Foo编写测试。 But if B doesn't override A.Foo , then you have to use your judgement. 但是,如果B没有覆盖A.Foo ,那么您必须使用您的判断。

All that said, it's really no different from having to write tests for any class that derives from another. 综上所述,这与为任何派生自另一个类的代码编写测试没有什么不同。 Consider deriving a class from TextWriter . 考虑从TextWriter派生一个类。 Would you write explicit unit tests for all of the virtual functions defined by the TextWriter class? 您是否会为TextWriter类定义的所有虚函数编写显式的单元测试? Or would you write tests only for those methods that you override, and those methods whose functionality might have changed as a side effect? 还是只为覆盖的那些方法以及其功能可能已经改变的那些方法编写测试?

There is a lot of opinions on what should be Unit Tested and what should not. 关于什么应该进行单元测试和什么不应该进行单元测试,存在很多意见。 My personal belief is that for every function you write, you should have written a unit test first to specify the desired behavior. 我个人认为,对于您编写的每个函数,都应该首先编写一个单元测试以指定所需的行为。 You then write your code to make this test pass. 然后,您编写代码以使此测试通过。 This is applicable for private, public, protected and internal. 这适用于私人,公共,受保护的和内部的。 If it is used it should be unit tested. 如果使用,则应进行单元测试。 Believe me this makes your life easier in the long run because if you or another developer changes existing unit tested code then a change in behavior is a lot more likely to be caught. 相信我,从长远来看,这会使您的生活变得更轻松,因为如果您或其他开发人员更改了现有的单元测试代码,那么行为更改很有可能会被抓住。

In the real world though it usually ends up being code first then test. 尽管在现实世界中,通常通常首先要编写代码然后再进行测试。 However they should still be written for all access levels. 但是,仍应针对所有访问级别编写它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM