Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should a concrete class that implements an interface have extra public methods for testing? [closed]

When implementing an interface on a concrete class, is it appropriate to have extra public methods exposed to help facilitate unit tests?

For example, let's say I have the following concrete class:

public class MyClass : IMyInterface
{
    public int InterfaceMethod(ComplexObject complexObject)
    {
        return NonInterfaceMethodOne(complexObject) 
            + NonInterfaceMethodTwo(complexObject);
    }

    public int NonInterfaceMethodOne(ComplexObject complexObject)
    {
        //Do complex logic that needs to be unit tested
    }
    public int NonInterfaceMethodTwo(ComplexObject complexObject)
    {
        //Do more complex logic that needs to be unit tested
    }
}

If I wrote my class this way, I could have unit tests for both non-interface methods, but I feel like this pattern is not correct. Is there a better way?

like image 480
dsacdalan Avatar asked Dec 14 '25 13:12

dsacdalan


1 Answers

What you have there looks perfectly acceptable to me. A general answer to your question is "it depends," because there could be scenarios where you want to hide those methods, and there could be scenarios where you want to expose them.

It's reasonable to consider your test suite as the first client of your code base, and it makes sense to support the needs of your client--you would still want to give careful consideration to what functionality you want to expose and hide.

In spite of the fact that NonInterfaceMethodOne and NonInterfaceMethodTwo are both public, if you inject this implementation into a parameter of the interface type, the client will still only have access to the interface method and will have no knowledge of the other 2 methods.

A client that is using the implementation will of course have access to all 3 methods, but will still not know how the interface method is implemented.

If it would be useful to expose those methods for unit testing and if you can determine that no damage is done by keeping the methods public, then keep them public.

But, it could still be appropriate to write your tests to ensure that NonInterfaceMethodOne and NonInterfaceMethodTwo work the way you want, then cover your interface method with another test(s), and then you may possibly no longer have a need for the unit tests covering NonInterfaceMethodOne and NonInterfaceMethodTwo--in which case you could remove these tests, and then make NonInterfaceMethodOne and NonInterfaceMethodTwo private--because your unit test(s) covering the interface method covers the other 2 methods.

  • and if you find that this approach doesn't hide any functionality that your test suite needs, I would lean toward this approach, because it's normally good to limit the functionality you expose
like image 84
egnomerator Avatar answered Dec 16 '25 04:12

egnomerator



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!