Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Derik Whittaker

Thoughts on Software Development, .Net, OOP, Design Patterns and all things cool



Is it evil to use reflection when testing?

I have a scenario where I have a private method that needs to be tested and the only way I can get to that method is by calling another public method and exercising all of its logic. 

This private method has a few different pathways and I would like to create tests for each of them.  I could do this by creating tests for the public method and just ensure that each of the tests exercise the various pathways of the private, but that just seems like too much work and effort.

So, my question to you is this.  Is it evil to use reflection to test a private method?

BTW, I know I could make the method internal and use the [InternalsVisibleTo] trick, but I do not want to make this method internal?

Thoughts, opinions, feedback,

Till next time,

[----- Remember to check out DimeCasts.Net -----]


Published Jul 29 2008, 06:55 AM by Derik Whittaker
Filed under:

Comments

Klaus Hebsgaard said:

My general thought on this is that you should NOT test private methods.

Some people go for a 100% code coverage, but that is crazy in my opinion.

It is much better to test the public methods that use the private methods.

This way you can keep the public interface tested and when you change the private implementation your tests don't have to be cahnged.

But then again i lean more towards Behavior testing...

# July 29, 2008 8:28 AM

Bryan Johns said:

I agree with Klaus.  It's better to test the public interface and not worry about the private methods.  Those should get tested with the public methods are tested.

# July 29, 2008 8:53 AM

Dan Malcolm said:

You could:

- Declare the method as protected

- Create a test wrapper class that inherits from the class you need to test, that will give you access to the protected methods. You can then make the call via the wrapper class.

This approach is used by tests in the ASP.Net MVC source code. ControllerActionInvokerHelper in the tests project inherits from ControllerActionInvoker. This allows tests to run specific stages of the controller execution lifecycle in isolation using the protected methods of the base class.

Not sure if this is acceptable in your scenario...

# July 29, 2008 8:55 AM

Derick Bailey said:

when I find myself in situations like this, it usually points to a poor design of the objects. You are likely in a situation where you might want to re-consider the methods that you have and why there are so many branches in the private method. perhaps a better abstraction could be used.

There are situations, of course, where you do have to deal with this and I say you should write tests against the public methods to ensure that all of the private methods are covered correctly.

Look at it this way - if you are not willing to unit test the public method so that it properly calls all the paths of the private method, then you are essentially saying that the private method is not worth the time and effort. If that's the case, then why do you even have the private method? If it's not worth taking the time to unit test properly, it's not valuable to the system and should be deleted.

...

but then, i'm one of those "crazy" people who achieves 100% code coverage by doing true TDD. (i love it when other people assert that their own opinions are the only way things can be - you don't need 100% coverage? great. more power to ya. I'll help you with what you need. You want 100% coverage - heck yeah, i'm here to help, still)

# July 29, 2008 9:03 AM

Klaus Hebsgaard said:

Dan in my opinion it is not OK to change the implementation of your code in order to test it. That is what you suggest...

But I am not a hardcore Unit Testing guy.

# July 29, 2008 9:05 AM

David said:

Beside the usual "hard to test indicates you should change your design" response, I don't think it's evil to test via reflection. You just have to weigh up the pros and cons. (Mocking frameworks all use reflection right? :))

My "official line" is here: davesquared.blogspot.com/.../assortment-of-basic-tdd-tips.html (search for "use test difficulties" for the relevant section).

# July 29, 2008 9:08 AM

Derick Bailey said:

wow, i really need to read what i'm posting. that totally came across arrogant. sorry about that.

# July 29, 2008 9:09 AM

W.Meints said:

Personally I think that you should avoid using reflection to test private methods. In my opinion you should test components as if you are using them from another component, thus only accessing members that are accessible to the component that uses the component you are testing.

I have used reflection to test a specific component, however it wasn't easy and you can't perform the usual compile-time checks on the code.

# July 29, 2008 9:11 AM

Davy Brion said:

"This private method has a few different pathways and I would like to create tests for each of them."

maybe it would make sense to apply the "Replace Method With Method Object" refactoring (www.refactoring.com/.../replaceMethodWithMethodObject.html).  Then you can simply test the new object properly without having to resort to reflection or other 'tricks'

# July 29, 2008 9:21 AM

Nick Berardi said:

Hi Derik,

No I think it is perfectly okay to use reflection in your tests.  In fact that is one of things that makes MSTest so useful, auto generated non-public properties and methods you can test.  

The only downside I see is the speed, but chances are that is probably not as important as testing the whole object.

# July 29, 2008 10:21 AM

Billy McCafferty said:

I've found one, and only one, very important location wherein I use reflection during testing.  I don't believe that a class' ID property (if it has one) should have a public setter; unless it has an assigned ID (which is evil).  Alternatively, the ID property's setter should be protected at most and be set by an ORM.  But it's handy during testing to have the ID set to > 0 in some situations (such as a controller's save method).  In these cases, I use reflection to set it.

# July 29, 2008 11:11 AM

Dan Malcolm said:

@Klaus

> Dan in my opinion it is not OK to change the implementation of your code in order to test it. That is what you suggest...

True. Protected member access for testing can be a useful bonus, but only if you genuinely intend the class to be subclassed.

# July 29, 2008 11:59 AM

redsolo said:

Well, I think it all depends on how easy it is to read and understand the test method. Its important the test method is understandable as it is a kind of documentation for the class and how it should be used. (And I dont mean hiding all setup code into a setup() method)

Ive noticed that when I have more mocking code than actual test code, then I should refactor out some logic from the class under test. If you have to much initial setup logic, then I would advise you to look into at the private method and see if it can be refactored out.

# July 29, 2008 5:34 PM

Matt Dunn said:

The MS testing suite includes a PrivateObject helper class exactly for this scenario. Interestingly when this was first announced, discussion around whether testing private members should be possible or not resulted in the same mixed results :)

blogs.msdn.com/.../150361.aspx

# July 29, 2008 9:37 PM

Brian Johnston said:

I use MSTest and just let it create the private accessors; then it's very simple to test...but your anti-MSTest as I recall?

I would never make a private method internal or protected or public just to wrap it or test it.  That's stupid.  Your trading security and scope for testing.

I 98% of the time use MSTest private accessors (automatically created and refactoring semi-included) and 2% of the time use reflection (but that is more for recursing into objects and isn't 'name' sensitive).  But I do test privates/internals/protected - how else can you say with 100% confidences that it works without making a bunch of tests on objects/methods that calls into those private object - but then your coupling your test to the knowledge of how the object works internally (so much for non-fragile tests if you go that route).

Take the time to learn MSTest - give it 1 month and push through the 'friction' - you will not want to go back - trust me on this.

# July 30, 2008 2:12 PM

surya gaddipati said:

yes ..it is . I think thats the whole point of TDD to point out  that when you are having to resort to tricks for testing then there is something wrong with your design.

# July 30, 2008 6:15 PM

Derik Whittaker said:

@Surya,

I would argue the wanting to test a private method may have nothing to do with design.  

It could have everything to do with wanting to create smaller more isolated tests.

If i made the method public doest that all of a sudden make the design better... NO.

Goal is to create smaller, leaner more efficient tests.

# July 30, 2008 6:24 PM

Bill Sorensen said:

I would echo the comments of Derick Bailey, Davy Brion, and redsolo. Try refactoring the code (perhaps with Replace Method with Method Object as Davy Brion suggested) so that the private logic can be tested in isolation.

Without seeing the specific example, it sounds like a code smell. The calling public method or the class itself has too many responsibilities or is too complex.

I'm sure there are cases where that does not apply, and yours may fall into that category. But "hard to test code" often means "highly coupled code with multiple responsibilities."

# July 31, 2008 2:43 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Derik Whittaker

Derik is a .Net Developer/Architect specializing in WinForms working out the northern suburbs of Chicago. He is also believer and advocate for Agile development including SCRUM, TDD, CI, etc.

When Derik is not writing code he can be found spending time with his wife and young son, climbing on his bouldering wall, watching sports (mostly baseball), and generally vegging out. Check out Devlicio.us!

Our Sponsors

Red-Gate!