One of my colleague ran into this typical dependency chain. The requirement was to show data in a Silverlight 3.0 data grid. Picture below summarizes the dependency chain. This picture is the very reason why we have IOC frameworks and how they make life easy. I mean, why should my Datagrid care about the fact that Synch framework is doing its job properly or not.
You can imagine how much time it would take for the developer working on the datagrid to resolve all the preceding 8 dependencies just to bind to the grid. Welcome to IOC (for those of you going “oh not again” please read on, there is little twist, at least it was for me).
Ideally we should only be concerned about our ViewModel and nothing else. Since ViewModel is using a WCF Proxy we already have an interface that we can mock. And here lies the key:
Mock the web service interface and inject it using the UnityBootstrapper
If you have basic Prism project injection should be straight forward. This is what we did in our bootstrapper:
this.Container.RegisterType<IMyService, MyServiceMock>();
myModel = IMyService.GetData();
Everything was smooth until this point in refactoring. Than I ran into trouble with actual mock implementation of the interface serialized in WCF proxy. Since all the methods get serialized into their corresponding Begin and End versions and the fact that everything in Silverlight 3.0 framework requires you to make asynchronous calls, you cannot just create straight interface mock and start binding.
Basically you have to be aware that you are mocking the asynchronous version of the interface and should not attempt to capture the underlying channel details in the mock. Given below is the code and new (much shorter and required) dependency chain I ended up with:
public class MyServiceMock : IMyService
{
public MyServiceMock()
{ }
#region IMyServiceMembers
public IAsyncResult BeginMyMethod(AsyncCallback callback, object asyncState)
{
callback.Invoke(null); // <—Trick your caller and tell them async operation complete right away
return null;
}
public ObservableCollection<MyClass> EndMyMethod(IAsyncResult result)
{
ObservableCollection<MyClass> mockedList = new ObservableCollection<MyClass>();
mockedList.Add(new MyClass());
return mockedList;
}
#endregion
}
*I am assuming no mocking framework is being used but the notion will still translate.
Here is the new dependency chain for testing my UI.
No comments:
Post a Comment