Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Unit Testing - Best Practices for hiding test seams in release code

I'm looking for some advice for unit-testing in a manner that doesn't leave "test hooks" in place in production code.

Let's say I have a static class (VB.NET Module) named MethodLogger who has a "void WriteEntry(string Message)" method that is intended to write the calling method and a message to a log file on disk. The actual target of WriteEntry() can be diverted to a fake implementation of IMethodLogger for running unit tests, and for all other cases it should call the real implementation of IMethodLogger.

Here's a rough-cut of what I've whipped up so far, and I like the approach--but in some quick tests it raises some questions and doubts:

[InternalAttributesVisibleTo("MethodLogger.Tests")]
internal static class MethodLogger
{
    public void WriteEntry(string message)
    {
        LogWriter.WriteEntry(message);
    }

    private IMethodLogger LogWriter
    {
        get;
        set;
    }

#if DEBUG
    internal void SetLogWriter(IMethodLogger logger)
    {
        LogWriter = logger;
    }
#endif
}

Here's my specific questions:

  • This tightly couples the unit tests to running against the DEBUG build; when I run unit tests though it appears that it doesn't specifically rebuild the assembly under test in DEBUG--is it possible to do so?

    • Would I ever want to run the unit tests against a non-debug build? Off the top of my head I see less value--but would there be?
  • Would it be possible for me to use a custom pre-compiler flag like "TEST" in lieu of "DEBUG"? How would I go about telling Visual Studio to always rebuild the target with this flag for testing to ensure my hooks / seams are available?

like image 315
STW Avatar asked Jul 16 '09 18:07

STW


People also ask

What makes code difficult for unit testing?

Tightly coupled code is extremely hard to unit test (and probably shouldn't be unit tested - it should be re-factored first), because by definition unit tests can only test a specific unit of something. All calls to databases or other components of the system should be avoided from Unit Tests because they violate this.


1 Answers

You could use Typemock Isolator to circumvent any design issues that hurt testability. unlike other frameworks, it will also work with static methods, private methods and non virtual methods. as you learn to better design, your code will be more "testable" by default, but if you want to just get around these issues now, this will help

http://blog.typemock.com/2009/01/isolator-new-vbnet-friendly-api.html

(also, it's the only tool with a VB friendly API)

like image 178
RoyOsherove Avatar answered Nov 15 '22 07:11

RoyOsherove