I recommend you read my async / await intro if you haven't already. You need to understand very well how the async methods relate to their returned Task in order to intercept them.
Consider the current implementation of Intercept . As svick said, it is better to avoid async void . One reason is that error handling is unusual: any exceptions to the async void methods are created directly on the current SynchronizationContext .
In your case, if the Proceed method throws an exception (for example, your layout), your implementation of async void Intercept will raise an exception that will be sent directly to the SynchronizationContext ( which by default - or the thread pool - SynchronizationContext , since this is a unit test , like I explain on my blog). Thus, you will see this exception raised in some thread in the pool of random threads, and not in the context of your unit test.
To fix this, you need to rethink Intercept . Regular interception only allows you to intercept the first part of the async method; in order to respond to the result of the async method, you will need to respond when the returned Task completed.
Here is a simple example that just grabs the returned Task :
public class MyInterceptor : IInterceptor { public Task Result { get; private set; } public void Intercept(IInvocation invocation) { try { invocation.Proceed(); Result = (Task)invocation.ReturnValue; } catch (Exception ex) { var tcs = new TaskCompletionSource<object>(); tcs.SetException(ex); Result = tcs.Task; throw; } } }
You might also want to run NUnit 2.6.2 or later, which adds support for async unit tests . This will allow you to await your MyInterceptor.Result (which will throw the exception correctly in the context of the unit test).
If you need a more sophisticated asynchronous capture, you can use async - just not async void .;)
// Assumes the method returns a plain Task public class MyInterceptor : IInterceptor { private static async Task InterceptAsync(Task originalTask) { // Await for the original task to complete await originalTask; // asynchronous post-execution await Task.Delay(100); } public void Intercept(IInvocation invocation) { // synchronous pre-execution can go here invocation.Proceed(); invocation.ReturnValue = InterceptAsync((Task)invocation.ReturnValue); } }
Unfortunately, the interception must be performed synchronously, so it is not possible to have asynchronous pre-execution (unless you synchronously IChangeProxyTarget for it to complete, or use IChangeProxyTarget ). However, even with this limitation, you should be able to do whatever you need using the methods above.