Tuesday, December 21, 2010

Assert.DoesNotThrow... why does it exist?

Take a look at this test:

[Test]
public void TestSomething()
{
   Assert.DoesNotThrow(MethodUnderTest);
}

It seems to me that it is functionally equivalent to this test:

[Test]
public void TestSomething()
{
    MethodUnderTest();
}

In other words, Assert.DoesNotThrow is the same as writing a test with no assertion. Is it really enough that the code runs without throwing an exception? Presumably the method under test is doing something, so shouldn't you verify those results with a stronger assertion?

Tuesday, December 7, 2010

AsyncController and custom action invokers

If you are trying to get AsyncControllers to work, you might run into this gem when you try to test your controller:

The resource cannot be found

If this happens to you, a custom action invoker is likely to be the culprit. In my case, I was using Castle Windsor, and I had extended ControllerActionInvoker to provide dependency injection to my action filters. My action invoker looked something like this:



And this is how I had registered the action invoker with Windsor (this assumes you are using a controller factory that is aware of Windsor):




All I had to change to fix the problem was to make my custom action invoker inherit AsyncControllerActionInvoker instead:



AsyncControllerActionInvoker implements IAsyncActionInvoker and adds a few new methods. Depending on what you are trying to accomplish with your custom invoker, you may need to override a few of these new methods as well.

Interestingly enough, I did not have to change how the invoker was registered with Windsor.

Monday, December 6, 2010

Using AsyncController with NServiceBus

With NServiceBus sometimes you do not want to allow a web request to complete until you have received some response from your message handler. For example, suppose you have defined the following message handler that returns a response code on success:

public class TestMessageHandler :
    IHandleMessages<TestMessage>
{
    public IBus Bus { get; set; }

    public void Handle(TestMessage message)
    {
        //Do something interesting...
        Bus.Return(0);
    }
}

This is a perfect scenario for using the asynchronous page API. It allows you to execute a potentially long-running operation on a separate thread outside of the IIS thread pool. While this thread is executing, the original request thread is returned to the thread pool. As a result, the asynchronous page API is great for I/O bound operations, since you keep threads in the thread pool ready to service requests and the new thread spends most of its time blocked on I/O. NServiceBus supports the asynchronous page API out of the box:

Bus.Send(new TestMessage()).RegisterWebCallback(callback, state);

Unfortunately, RegisterWebCallback does not work with ASP.NET MVC. If you are using ASP.NET MVC, you can use AsyncController, which was introduced in ASP.NET MVC 2. The following code illustrates how you might use AsyncController to wait for a response the message handler:

public class TestController : AsyncController
{
    private IBus bus;

    public TestController(IBus bus)
    {
        this.bus = bus;
    }

    public void IndexAsync()
    {
        AsyncManager.OutstandingOperations.Increment();

        bus.Send(new TestMessage()).Register(Callback);
    }
    public ActionResult IndexCompleted()
    {
        return View();
    }
    
    private void Callback(int responseCode)
    {
        AsyncManager.OutstandingOperations.Decrement();
    }
}

As you can see, the AsyncController API is a little awkward (though it is an improvement over the asynchronous page API, in my opinion), but it is a small price to pay for scalability.