Faking Async Calls in WCF – Part I

Once upon a time, I wrote about writing tests for WCF servers and clients. WCF can be invoked also in an async method. What you would do is generate WCF proxies that have method definition for your service starting with “Begin…” and “End…”, following the asynchronous method calling convention.

As you may recall from our last session, eons ago, my server looks like this:

[ServiceContract(Namespace = "http://DoesntExist")]
public interface ISourceListProvider
{
[OperationContract]
string GetSourceList(string source);

}

And my calling and invoking methods look like this:

public IAsyncResult GetSourceListFromServerAsync(string source)
{
return channel.BeginGetSourceList(source, GetSourceListCallBack, channel);
}

public void GetSourceListCallBack(IAsyncResult ar)
{
sourceList = ((ISourceListProvider) ar.AsyncState).EndGetSourceList(ar);
    Console.WriteLine(sourceList);
}

public string SourceList
{
get
{
return sourceList;
}
}

The sourceList attribute gets updated at the end of the operation.

What I want to do is short-circuit the async call. Let’s imagine that the async call takes 1 second from starting, until End gets called. Instead of calling the method asynchronously, I want to wait 1 second, and then call the End method. In fact, I’m testing the client, and faking the server, but keeping the delay.

Here’s my test (there’s a small setup code in the TestInitialize that appear :

   1:  private IAsyncResult returnedHandle;  
   2:  public delegate void AsyncProcessor(Delegate d);  
   3:     
   4:  [Isolated] 
   5:  [TestMethod]  
   6:  public void AsyncGetSourceList_SimulatedAsync_WithFakeResult()  
   7:  {  
   8:      Isolate.WhenCalled(()=>fakeSourceListProvider.BeginGetSourceList(null, null, null))  
   9:          .DoInstead(c=>  
  10:                         {  
  11:                             AsyncProcessor dr = d=>  
  12:                                                 {  
  13:                                                     Thread.Sleep(1000);  
  14:                                                     d.DynamicInvoke(returnedHandle);  
  15:                                                 };  
  16:                             returnedHandle = dr.BeginInvoke(c.Parameters[1] as Delegate, null, c.Instance);  
  17:                             return returnedHandle;  
  18:     
  19:                         });  
  20:      Isolate.WhenCalled(()=>fakeSourceListProvider.EndGetSourceList(null)).WillReturn("Fake Result");  
  21:      DataProviderClient providerClient = new DataProviderClient();  
  22:      IAsyncResult myHandle = providerClient.GetSourceListFromServerAsync("");  
  23:     
  24:      while (!myHandle.IsCompleted)  
  25:      {  
  26:          Console.WriteLine("Waiting...");  
  27:          Thread.Sleep(100);  
  28:      }  
  29:      Assert.AreEqual("Fake Result", providerClient.SourceList);  
  30:     
  31:     
  32:  }

It’s a bit long, so let’s step through it. In line 2, I declare a delegate called AsyncProcessor. This delegate is going to be invoked on another thread, and will simulate the server operation.

In lines 8-19, I use the new and ingenious DoInstead on the Begin method. It lets me define the custom code that will be executed when the Begin method gets called. In our case, the custom code is calling our delegate asynchronously. On the other thread, the delegate includes sleeping for the timeout, and then calling the End method.

In line 20 I set the return value I want to simulate coming from the server. That’s all I need to do!

I used the Console.WriteLine calls to show what happens when I wait for the method to return. When I run it, here’s what happens:

image

This is pretty cool by itself. But wait, there’s more! In my next post, I’m going to do a bit more magic.

TOP