简体   繁体   中英

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

Using 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 . 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 .

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. 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 .

Obviously, if B overrides Foo , then you have to write a test for B.Foo . But if B doesn't override A.Foo , then you have to use your judgement.

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 . Would you write explicit unit tests for all of the virtual functions defined by the TextWriter class? 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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