Making sure all IWorker implementers call CanHandle from Handle without a mocking framework

lego-568039_1280

You have an interface that allows you to treat all worker classes – classes that handle a specific type of work – as just one type: IWorker;

    interface IWorker
    {
        public Boolean CanHandle(IWork work);
        public void Handle(IWork work);
    }

You want your worker classes to be able to do their work without having to check their backs every step of the way.

BUT

You have no way of guaranteeing that the classes that are handing out work to workers call Handle only if CanHandle returns true.

This may be a bit of a contrived example, as in this case you’d probably be better off avoiding the problem altogether. But for the sake of argument let’s say that is not an option and that the calling `CanHandle` from `Handle` is just an example of you needing to make sure that the implementer of one method always calls another and and acts according to the returned value.

To make every worker call CanHandle itself and only proceed with the actual work if everything is ok, you could of course provide a base class that does this. Ensuring with tests that the base class sticks to the pattern of calling CanHandle from Handle would be easy to do. And it would allow specific workers to focus on their own specific processing.

Hang on though … having such a base class kinda defeats the object of having an interface: not tying yourself to a distinct class hierarchy.

So how can you ensure that every class that implements the IWorker interface has implemented its Handle method in a way that protects the actual processing code from being handed cows when it is designed to handle chickens? Working out that you ended up with a sliced and diced pair of jeans because some distributor blindly handed your Levi’s to a kitchen worker instead of a laundry worker, is not exactly fun or easy.

The way to protect yourself from late night debugging sessions has three parts:

  • You need a way to test every class implementing IWorker with the same set of tests.
  • You need a way to substitute the actual implementation of CanHandle with an implementation that does exactly what your tests need it to do.
  • You need two tests to verify that Handle calls CanHandle and proceeds in accordance with what CanHandle returns.

1. Executing the same tests for every class implementing IWorker

Ensuring that every implementer of IWorker is tested with the same set of tests, is pretty simple when you are using NUnit and not much more difficult when using MSTest (just a little more work).

When using NUnit this boils down to using a generic test class and using the TestFixture attribute to specify the classes to be tested.

    [TestFixture(typeof(KitchenWorker))]
    [TestFixture(typeof(BathroomWorker))]
    class IWorker_ContractTests<T> where T : IWorker, new()
    {
        IWorker MakeWorker()
        {
            return new T();
        }

        [Test]
        public void TestMethod1()
        {
            IWorker worker = MakeWorker();
            // ...snip...
        }
    }

For more information check out these two posts:

2. Substituting CanHandle

To verify that Handle acts according to what CanHandle returns, you need to be able to control what CanHandle returns. This means you need to substitute the actual implementation of CanHandle with whatever your tests needs it to do.

Using a mocking framework that is a piece of cake. But what if you can’t use a mocking framework?

Oops?!?

Yup. Without a mocking framework you are definitely in a bit of a pickle.

Unless…

When dealing with interfaces, you always have the option of wrapping the implementing class that you want to test in a “Test wrapper” and selectively delegate its methods to the “actual” implementer. Something like this.

    class TestWrapper : IWorker
    {
        IWorker _WorkerUnderTest;
        EnsureCanHandle _ReturnsThis;

        public TestWrapper(IWorker workerUnderTest, EnsureCanHandle returnsThis)
        {
            _WorkerUnderTest = workerUnderTest;
            _ReturnsThis = returnsThis;
        }

        public Boolean CanHandle(IWork work)
        {
            return (_ReturnsThis == EnsureCanHandle.ReturnsTrue);
        }

        public void Handle(IWork work)
        {
            _WorkerUnderTest.Handle(work);
        }
    }

    enum EnsureCanHandle
    {
        ReturnsFalse,
        ReturnsTrue
    }

The test wrapper in this example takes the actual worker to be tested as the first parameter of its constructor. The second parameter dictates the result that CanHandle will return. The test wrapper’s implementation of CanHandle does what is required by the test, while its implementation of Handle delegates to the actual worker.

3. Testing Handle

You want all classes implementing IWorker to call CanHandle from Handle. And you only want Handle to proceed with the actual work when CanHandle returns true. When CanHandle returns false, Handle should throw an IndecentProposalError.

To achieve this using our test wrapper, you need to tweak the MakeWorker helper method of the generic test class to take a parameter that will dictate the result CanHandle returns. And of course you need to pass the desired CanHandle result in each of your tests. After that, all that’s left to do is to write the actual tests.

Like so.

    [TestFixture(typeof(KitchenWorker))]
    [TestFixture(typeof(BathroomWorker))]
    class IWorker_ContractTests<T> where T : IWorker, new()
    {
        IWorker MakeWorker(EnsureCanHandle returnsThis)
        {

            return new TestWrapper(new T(), returnsThis);
        }

        [Test]
        public void Handle_CanHandle_Returns_False_Should_Throw_IndecentProposalError()
        {
            IWorker worker = MakeWorker(EnsureCanHandle.ReturnsFalse);
            IWork work = new Work_Fake();

            Assert.Throws<IndecentProposalError>(
                delegate
                {
                    worker.Handle(work);
                }
            );
        }

        [Test]
        public void Handle_CanHandle_Returns_True_Should_Not_Throw_Anything()
        {
            IWorker worker = MakeWorker(EnsureCanHandle.ReturnsTrue);
            IWork work = new Work_Fake();

            Assert.DoesNotThrow(
                delegate
                {
                    worker.Handle(work);
                }
            );
        }
    }

That’s it. That’s how you make sure all classes implementing IWorker call CanHandle from Handle and proceed appropriately when you can’t use a mocking framework. Enjoy!

What code had you wondering how to test it? I’d love hearing from you by email or in the comments below. I read everything and will try to help where and as best I can.

Posted in Software Development
Tags: , , , , , , , , , , , , ,

How to verify a method actually gets called – without a mocking framework

hard-labor

Hard labor

You have busted your bum writing a solid MagnificentValidation validation method that checks the input data for a whole slew of data manipulation methods. And you, of course, covered it with unit tests so nobody, not even you, can accidentally mess up the validation logic without it being noticed.

Yes!

But wait… what if…

How do you ensure that your rock solid data validation is not inadvertently deactivated? You can’t for the life of you imagine why anybody would do that, but hey, (sh)it happens!

You want a safety net. One that ensures that all data manipulation methods actually do call your MagnificentValidation method.

Obviously that means that you need to write a test for those data manipulation methods. That test needs to call a data manipulation method and verify that MagnificentValidation was called.

Sounds easy enough. And it is when you use a mocking framework. But what if you don’t? What do you then put in the assert part of such a test?

Verifying MagnificentValidation is called

Verifying that MagnificentValidation is called depends entirely on its implementation.

explosion

When MagnificentValidation throws exceptions

Validation methods throwing exceptions are usually the easiest to check for being called. All you need to do is feed the calling method invalid data and check that the exception is actually thrown.

Using MSTest you would need to use the ExpectedException attribute, or code a try catch yourself. Using NUnit, or any other unit testing framework whose Assert class supports checking for exceptions being thrown, you can use its equivalent of an Assert.Throws() assertion in your test.

See Testing strategy for validation and action methods for an example.

side effects

When MagnificentValidation has other side effects than exceptions

Validation methods that have other side effects than exceptions are a little harder to check for being called. But not by much. Instead of checking for an exception being thrown, you now just call DataManipulation and then check for the expected side effect, for example an ErrorText property that given the implementation of MagnificentValidation should no longer have an empty string as its value.

See Verify a validation method is called that doesn’t throw exceptions for an example.

function

When MagnificentValidation does not have side effects but returns a result

Validation methods that do not have any side effects at all but “just” return a result are hardest to check for being called. The result they return is after all not visible to your test, but only to the calling method.

That means that the only way you can check that YourDataManipulation method calls MagnificentValidation is by the behavior you expect from YourDataManipulation given invalid input.

Yup, that means “repeating” the implementation of a test on methods calling MagnificentValidation. May feel soggy, but is very much advised as the intention of the test is wildly different from the actual behavioral tests.

Tests do more than verify behavior. They also serve as documentation of every aspect of your class’ behavior. Each test represents a different piece of knowledge about your class. Something that should be reflected in the name of the test method. If two tests happen to have the (almost) same implementation, that is … well … an implementation detail.

This was first discussed in How can you check a validation method is called if it just returns an error code.

Conclusion

While mocking frameworks may make it easy to verify that a method was called, DIYing such checks isn’t exactly rocket science either if you know how to go about it.

That’s it. Enjoy!

What code had you wondering how to test it? I’d love hearing from you by email or in the comments below. I read everything and will try to help where and as best I can.

Posted in Software Development
Tags: , , , , ,

4 surprises with asserts moving from Delphi to C#

QuestionMark_Exclamation-Point

Moving from Delphi to C# is fun most of the time.

Discovering stuff I can do in C# that is impossible, or (very) time consuming, in Delphi is fun. Discovering that stuff I take for granted in Delphi – i.e. metaclasses (officially “class references”), not having to re-declare constructors to use them to instantiate descendant classes – is impossible in C#, is less fun, but still interesting.

Sometimes I am just plain astonished, if not to say flabbergasted.

One such occurrence happened a couple of weeks ago. I was working on some code where I was putting a call to a validation method in a Debug.Assert to check for contract violations. I naively assumed that C#’s Debug.Assert would behave in a very similar manner to Assert in Delphi. And was completely taken off guard by the differences.

Assert in Delphi

In Delphi the Assert looks as follows. (The message part is optional.)

    Assert({boolean expression}False, 'Message used when the boolean expression evaluates to false.');

When you call Assert in Delphi and the boolean expression evaluates to false this raises (throws) an EAssertionFailed exception.

The beauty of an exception being raised is that it enables you to use Assert calls to ensure a method’s contract is met. The exception guarantees that execution won’t proceed beyond the Assert call when the contract is violated. Barring any except (catch) and finally blocks of course.

You can control whether assertions are compiled into an executable using an “Assert directive”

    {$C+} 
    // or 
    {$ASSERTIONS ON} 
    // to turn assertions on, and 
    {$C-} 
    // or 
    {$ASSERTIONS OFF}
    // to turn them off

As the Assert directive has local scope, you can keep some asserts even when all others are turned off. Using the {$IFOPT xxx} directive you can even create a construct that reinstates the project scope value after your local overrule.

This is the way my world has worked for the good many years that I have developed using Delphi.

Enter C#

And see my world turned on its head.

The Debug class is where you turn for Assert‘s.

Or is it?

Surprise 1. Two classes offering Assert

First surprise was that there are two classes you can use for assertions: Debug and Trace. The Assert overloads have the exact same functionality in both classes.

Why?

Apparently Debug.Assert the calls are automagically removed from assemblies compiled when the DEBUG conditional is not defined, while Trace.Assert calls are always compiled into an assembly.

And that was the second surprise.

Surprise 2. DEBUG conditional dictates inclusion and exclusion

The Delphi convention certainly is that you turn assertions on for debug builds and off for release builds, but there is no one holding a gun to your head.

In fact there can be many reasons to include some assertions in release builds, while excluding others.

For one, the code run to evaluate the boolean expression may have side effects that you do not want to miss out on. See Assertions in Managed Code for an example.

For another, some checks are more important than others. While you might be willing to forego the contract checks of most assertions, there are some checks where you want to guarantee that the code protected by that check is never executed if the contract was violated.

The choice in C# certainly seems more “elegant”: use Debug.Assert if you are ok with excluding the check, use Trace.Assert if you want to keep it. A lot easier and more readable than using IFDEF and/or IFOPT directives.

So, simply use Trace.Assert for any Assert you want to make it into your assembly regardless of whether you created a DEBUG or a release build?

Well … No.

Enter surprises number three.

Surprise 3. Asserts in C# bring up dialogs

According to the MSDN documentation, Debug.Assert:

Checks for a condition; if the condition is false, outputs messages and displays a message box that shows the call stack.

Scuse me? What the bleep?

How about Trace then? That is set to compile into release builds, so it wouldn’t really bring up a dialog now would it? Well, unfortunately, it does. The documentation for Trace.Assert is – letter by letter – exactly the same as for Debug.Assert.

Which means that if you are building servers and services, you’d better steer clear of Trace for protecting your code against contract violations. I wouldn’t want to be the developer that caused a sysop or devop to have to respond to a call in the middle of the night to close a dialog so the server/service can continue …

And even if there were some – as yet unknown to me – feature in .Net that would suppress the dialogs in code running as a Windows’ service, I still can’t use Trace to protect my code against contract violations.

And that was surprise number four.

Surprise 4. Asserts in C# do not throw exceptions

Having read the description in the docs for the Assert method of both the Debug and Trace classes, it took quite some time for the full implications of those dialogs to hit me. If that felt like lightning, the realization that followed felt like an earthquake.

Asserts in C# do not throw exceptions.

Yes, I know that when you turn off assertions for release builds in Delphi, you won’t get any exceptions either and your code is not protected from contract violations, but… they do do so in debug builds and they do do so for assertions that you “keep” in release builds even when turning off the large majority of your asserts.

So Trace.Assert not throwing an exception when the “condition is false” is a big deal. Because when the code continues to execute in a situation with arguments that it wasn’t designed to handle, that tends to produce the most horrific and hard to debug subtle errors.

Surprise recovery

Is there a way to recover from these surprise?

Yup! Of course, there is.

To get the behavior I expect from an Assert call, I just coded up two simple classes: DebugEx and TraceEx. They give me the best of both worlds. The ease of selecting whether the Assert makes it into a release build from C# with the exception throwing protection of code from Delphi.

    class AssertionFailure : Exception 
    {
        public AssertionFailure() : base() { }
        public AssertionFailure(string message) : base(message) { }
        //public AssertionFailure(SerializationInfo info, StreamingContext context) : base(info, context) { }
        public AssertionFailure(string message, Exception innerException) : base(message, innerException) { }
    }

    class DebugEx
    {
        [Conditional("DEBUG")]
        public static void Assert(bool condition)
        {
            if (!condition)
                throw new AssertionFailure("Assertion condition failed.");
        }
        
        [Conditional("DEBUG")]
        public static void Assert(Boolean condition, string message)
        {
            if (!condition)
                throw new AssertionFailure(message);
        }

        [Conditional("DEBUG")]
        public static void Assert(bool condition, string message, string detailMessage)
        {
            if (!condition)
                throw new AssertionFailure(string.Join("\n", message, detailMessage));
        }
        
        [Conditional("DEBUG")]
        public static void Assert(bool condition, string message, string detailMessageFormat, params object[] args)
        {
            if (!condition)
                throw new AssertionFailure(string.Join("\n", message, string.Format(detailMessageFormat, args)));
        }
    }

    class TraceEx
    {
        public static void Assert(bool condition)
        {
            if (!condition)
                throw new AssertionFailure("Assertion condition failed.");
        }

        public static void Assert(Boolean condition, string message)
        {
            if (!condition)
                throw new AssertionFailure(message);
        }

        public static void Assert(bool condition, string message, string detailMessage)
        {
            if (!condition)
                throw new AssertionFailure(string.Join("\n", message, detailMessage));
        }

        public static void Assert(bool condition, string message, string detailMessageFormat, params object[] args)
        {
            if (!condition)
                throw new AssertionFailure(string.Join("\n", message, string.Format(detailMessageFormat, args)));
        }
    }

That’s it. Enjoy!

What had you scratching your head when moving to C#? I’d love hearing from you. Just let me know in the comments below or by email.

Posted in Software Development
Tags: , , , , , , ,

How can you check a validation method is called if it just returns an error code

The strategy laid out in Testing strategy for validation and action methods calls for a single test per action method, to show that it actually calls the validation method.

With an exception throwing validation method that test is simple. But with error code returning validation – there is no exception to wait for!

And this time you are not so lucky that your validation method has some other side effect that you can check for. So you can’t even use the method discussed in How to ensure a validation method is called that doesn’t throw exceptions!

No need to panic.

The answer lies in the the remainder of the test strategy: the tests you write to check each action method’s behavior given both valid and invalid input. To check that the validation method is called you simply check for the behavior expected for either valid or invalid input.

But, wait…

Doesn’t that mean the single test to show the validation is called, replicates one of the tests to check the action methods behavior?

Sure does!

Isn’t that bad? A gross violation of DRY?

Don’t think so.

It may FEEL wet, but it isn’t.

The intention of a test to show a method is called and of a test to verify the behavior given valid or invalid input, are miles apart. Tests do not just (!) verify behavior. They also serve as documentation of every aspect of your class’ behavior. Each test represents a different piece of knowledge about your class.

And that is also why you name each test in a way that reflects exactly what aspect of your class’ behavior it is verifying.

The fact that the test to show a method is called may have (almost) the same implementation as a test to verify the behavior given invalid or valid input, is therefore an … implementation (sic) detail and – in my not so humble opinion – totally irrelevant.

That’s it. Enjoy!

What code had you wondering how to test it? I’d love hearing from you by email or in the comments below. I read everything and will try to help where and as best I can.

Posted in Software Development
Tags: , , , ,

Designing your way out of the CanHandle-Handle conundrum

CanHandle – Handle pattern conundrum

When you have multiple classes implementing an IWorker interface with a CanHandle and Handle method, such as

interface IWorker
{
    public Boolean CanHandle(IWork work);
    public void Handle(IWork work);
}

you find yourself in a conundrum: should you call CanHandle again from Handle?

If you don’t, someone could pass in work that a worker isn’t designed to handle and that can lead to a multitude of different exceptions or subtle, very hard to debug errors. Avoiding those errors was a vote in favor of calling CanHandle from Handle, while the double execution of CanHandle for well behaved clients of your IWorkers was a vote against it.

A previous post – Act like a pessimist and call CanHandle from Handle (again)? – discussed a way out of the conundrum by putting the CanHandle call in an Debug.Assert statement.

That’s a perfectly valid approach. But… what if you could avoid the conundrum altogether?

Avoiding the conundrum

The problem with a class with one method that validates X, and another method then processes X is that you make that class hugely dependent on its clients and you need to take steps to ensure that people use your class the way it was intended to be used.

Why not make it simpler for everyone involved? Simpler for clients of your workers and simpler for your worker classes themselves.

What is the reason for having a CanHandle method to begin with?

The answer usually is that anyone with work to be done can now find a worker that says “yay, I can handle this” and then pass off the work to that worker.

So a client of your workers (usually a work distributor of some sort) would execute a loop like:

    ICollection<IWorker> _Workers;

    public void Distribute(IWork work)
    {
        foreach (var worker in _Workers)
        {
            if (worker.CanHandle(work))
            {
                worker.Handle(work);
                break; 
            }   
        }
    }

But why make a client of your workers pose the question at all? After all, anyone with work looking for a worker to do it, really is only interested in getting their work done.

So … why not simply have them pass the work to the Handle method directly? All you then need to do is make Handle itself check whether it can actually Handle the work and respond accordingly.

    public Boolean Handle(IWork work);

Using this approach the loop in a work distributor would look like:

    public void Distribute(IWork work)
    {
        foreach (var worker in _Workers)
        {
            if (worker.Handle(work))
                break;
        }
    }

Good. And you can make it even better.

Polishing the alternative

Previously, Handle would try to execute the work that it received and only fail to do see as a result of errors or exceptions. Now though, when you call Handle you need to check whether the work was actually accepted for execution. That makes Handle a bit of a misnomer. Accept sounds better.

Another peeve with the above method is that a Boolean result isn’t very descriptive. What does it mean when the method returns false? Was the work not accepted, or was it accepted and was the execution of that work unsuccessful? Personally, I nowadays only use Boolean result values for methods answering a CanXxx, IsXxx, DidXxx, HasXxxx question. In other cases, I prefer a bit more self-documentation and use descriptive enums for parameter and result types. Even if those enums only contain two members.

In this case for example:

    enum AcceptWorkResponse
    {
        Rejected,
        Accepted
    }

This type of return value makes it clear that the work can be rejected. It also conveys that the work has, so far, only been accepted and may not necessarily have been done yet. For example when the work will be executed in a separate thread.

Your Handle, now named Accept, method then is declared as:

    public AcceptWorkResponse Accept(IWork work);

And the loop becomes:

    public void Distribute(IWork work)
    {
        foreach (var worker in _Workers)
        {
            if (worker.Accept(work) == AcceptWorkResponse.Accepted)
                break;
        }
    }

Yes! Much more self-documenting.

Final touch

As the Accept method is now itself telling clients of the IWorker interface whether the work will be done, there is no need to keep CanHandle around. Doing so would only serve to confuse matters.

If you keep it in a class implementing the IWorker interface, do reduce its accessibility level to at most protected, preferably to private. After all, whether a class implementing IWorker can handle some work is now an implementation detail of the Accept method and doesn’t have to be exposed any further than absolutely necessary.

When you no longer have a CanHandle method, you can simply write all the tests on the Accept method. It no longer matters how it determines its answer to whether it will do the work, just as long as it responds appropriately to the work it is handed.

That’s it. Enjoy!

What code had you wondering how to test it? I’d love hearing from you by email or in the comments below. I read everything and will try to help where and as best I can.

Posted in Software Development
Tags: , ,

Does your code defy you?

Sign up now and receive a regular influx of practical unit testing and software design tips to make your code more testable and improve its design. One small step at a time.
* = required field