Tuesday, 5 March 2013

Unit Testing Internal Methods

I’ll come straight out with it, I don’t like unit tests residing within the dll that they are testing, I know that some people quite like this approach and it could be argued that it allows the clients to verify that the unit tests are indeed in place and working correctly.

http://proudsalopian.files.wordpress.com/2013/02/dotcover-results.png

For me though they are not a part of the production code and just add unnecessary bloat to it, this is allied to the fact that sometimes test rely on the infrastructure and there may also be a set amount of database interaction which for a live client is a big no no!

Instead I prefer all of my unit tests to be in a single or suite of test projects that are invoked sometime during the build process to verify the quality of the code. Recently we have been retroactively fitting some unit-testing to new functionality within a legacy project (which means that we do not of course have dependancy injection!) and I came up against an issue that we have come up against before but have always cludged our way around. The issue is one of scope, I like to test the validation routines for the business layer in isolation but we never ordinarily make our business layer validation methods public instead relying on the main ‘Update’ method to perform the validation prior to save. I like to call the validation methods in isolation because it means that the tests are more performant which in turn means you can be more thorough and reap the rewards of a more stable and tested application. Ideally I like to make the validation methods private or protected but for the sake of unit testing I will compromise and make them internal, this way they can be invoked from anywhere within the business layer but NOT from outside. OK, now scan back to my first paragraph and you can see where my problem lies… I don’t like unit tests in the dll itself.

Luckily .NET has a solution to this problem in that internal methods may be made visible to named external libraries; thus our unit testing library can invoke the required validation methods without exposing the same methods in the public API. However, all of the examples I have seen for implementing this are very poorly documented and so I thought as an aide memoire for myself, and as a service to the internet at large I would share my experiences.

To find out more, visit Conrad's full blog here.

Written by Conrad Rowlands, Senior Developer, DSCallards
Visit:  www.dscallards.com

No comments:

Post a Comment