Testing private methods using RhinoMocks

2019-06-25 08:35发布

问题:

I work in TDD environment and basically I am facing with a dilemma which I think is very important in TDD environment. As a programmer, you want your methods to be as readable as possible. To achieve that, we tend to partition our methods in multiple private methods as well. While doing that all that code which was moved to the private function looses it's test ability.

Rhino test class cannot see all those private methods and I need to be able to run tests against those methods as well. I do not want them to be public because it does not make sense to keep them public.

Any ideas?

回答1:

If I qoute a part of your question:

[...] we tend to partition our methods in multiple private methods [...]

This is wrong. If you follow a single responsibility principle and good OOP design, your methods would be much independent and simpler. If you feel like you want to extract a yet another private method to make your public one look shorter, give it a thought first. Maybe, you can refactor it in a separate class?

You do not test private methods, because you test public contracts and not the details of implementations. If you want to have something distantly similar to private methods testing, make them internal and set InternalsVisibleTo attribute.

Another method (pointed by R. Harvey) is to write a wrapper class that wraps you private methods into public ones. This approach has a benefit that you don't need to make your private methods internal. The downside is that for every private method you will have a wrapper public method. So the amount of methods may double.



回答2:

As suggested by others, one way to test non-public methods is to make them internal and use InternalsVisibleTo attribute. However, I would strongly suggest against that.

Private methods should be covered by unit tests by testing public methods that use them. Of course, as time progresses and you add more functionality to the class under test, it gets more and more complicated to setup your tests. This is a good indicator that the class has too much responsibility and you should split it into multiple smaller classes. You can then make these smaller classes a dependency of original class and mock them in your tests - that will simplify the tests again.

While doing that, you don't have to entirely relinquish private methods - it's a good idea to use them to make your code more readable without using comments.