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