Having used NUnit and Rhino for middle and service layer for past 4-5 years, I was feeling very comfortable with TDD. And then I joined this new WPF/Prism project and faced the real pain!
Using TDD in middle, service or data layer is normally easier and straight forward but when it comes to presentation layer it seems it still little cumbersome even though you are using MVVM . Using DI, IoC and MEF are adding the complexity to write simple unit test in presentation layer. As we are using a Prism like framework for this project, we faced a lot of challenges in writing unit test. Luckily we found solution for almost all these problems.
One of the key problem we faced is mocking the IServiceLocator. Since we are using a lot of base classes coming from framework (Third Party component with no source code!), it was really a challenge in configuring container for service locator. In most of the cases developer doesn’t have any clue about what and all types need to be register in container so that base type should not throw object reference not set exceptions.
To solve the above problem, I created a MockServiceLocator and MockContainer class that is able to resolve literally any type that is having an interface. Here is the sample code snippet:
- using System;
- using Microsoft.Practices.ServiceLocation;
- using Microsoft.Practices.Unity;
- using System.Collections.Generic;
- namespace UnitTestHelper
- {
- public static class MockServiceLocator
- {
- public static IServiceLocator GetMockServiceLocator
- {
- get
- {
- IUnityContainer container = new UnitTestHelper.MockUnityContainer();
- return new UnitTestHelper.UnityServiceLocatorAdapter(container);
- }
- }
- }
- public class MockUnityContainer : IUnityContainer
- {
- public Func<object> ResolveMethod { get; set; }
- public Func<IEnumerable<object>> ResolveAllMethod { get; set; }
- public IUnityContainer Parent
- {
- get { throw new System.NotImplementedException(); }
- }
- public IEnumerable<ContainerRegistration> Registrations
- {
- get { throw new NotImplementedException(); }
- }
- #region Implementation of IUnityContainer
- public IUnityContainer RegisterType(Type from, Type to, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterInstance(Type t, string name, object instance, LifetimeManager lifetime)
- {
- return this;
- }
- public void Teardown(object o)
- {
- throw new System.NotImplementedException();
- }
- public IUnityContainer AddExtension(UnityContainerExtension extension)
- {
- throw new System.NotImplementedException();
- }
- public object Configure(Type configurationInterface)
- {
- throw new System.NotImplementedException();
- }
- public IUnityContainer RemoveAllExtensions()
- {
- throw new System.NotImplementedException();
- }
- public IUnityContainer CreateChildContainer()
- {
- return this;
- }
- public IUnityContainer AddNewExtension<TExtension>() where TExtension : UnityContainerExtension, new()
- {
- throw new NotImplementedException();
- }
- public object BuildUp(Type t, object existing, string name)
- {
- throw new NotImplementedException();
- }
- public object BuildUp(Type t, object existing)
- {
- throw new NotImplementedException();
- }
- public T BuildUp<T>(T existing, string name)
- {
- throw new NotImplementedException();
- }
- public T BuildUp<T>(T existing)
- {
- throw new NotImplementedException();
- }
- public TConfigurator Configure<TConfigurator>() where TConfigurator : IUnityContainerExtensionConfigurator
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterInstance(Type t, string name, object instance)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterInstance(Type t, object instance, LifetimeManager lifetimeManager)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterInstance(Type t, object instance)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterInstance<TInterface>(string name, TInterface instance, LifetimeManager lifetimeManager)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterInstance<TInterface>(string name, TInterface instance)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterInstance<TInterface>(TInterface instance, LifetimeManager lifetimeManager)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterInstance<TInterface>(TInterface instance)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType(Type t, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType(Type t, string name, params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType(Type t, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType(Type from, Type to, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType(Type from, Type to, string name, params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType(Type from, Type to, params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType(Type t, params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType<T>(string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType<T>(string name, params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType<T>(LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType<TFrom, TTo>(string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers) where TTo : TFrom
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType<TFrom, TTo>(string name, params InjectionMember[] injectionMembers) where TTo : TFrom
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType<TFrom, TTo>(LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers) where TTo : TFrom
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType<TFrom, TTo>(params InjectionMember[] injectionMembers) where TTo : TFrom
- {
- throw new NotImplementedException();
- }
- public IUnityContainer RegisterType<T>(params InjectionMember[] injectionMembers)
- {
- throw new NotImplementedException();
- }
- public object Resolve(Type t, string name)
- {
- return Rhino.Mocks.MockRepository.GenerateStub(t);
- }
- public object Resolve(Type t)
- {
- return this.ResolveMethod();
- }
- public T Resolve<T>(string name)
- {
- throw new NotImplementedException();
- }
- public T Resolve<T>()
- {
- throw new NotImplementedException();
- }
- public System.Collections.Generic.IEnumerable<object> ResolveAll(Type t)
- {
- throw new NotImplementedException();
- }
- public System.Collections.Generic.IEnumerable<T> ResolveAll<T>()
- {
- throw new NotImplementedException();
- }
- #endregion
- #region IDisposable Members
- public void Dispose()
- {
- throw new NotImplementedException();
- }
- #endregion
- public object BuildUp(Type t, object existing, string name, params ResolverOverride[] resolverOverrides)
- {
- throw new NotImplementedException();
- }
- public object Resolve(Type t, string name, params ResolverOverride[] resolverOverrides)
- {
- return Rhino.Mocks.MockRepository.GenerateStub(t);
- }
- public IEnumerable<object> ResolveAll(Type t, params ResolverOverride[] resolverOverrides)
- {
- throw new NotImplementedException();
- }
- }
- public class UnityServiceLocatorAdapter : ServiceLocatorImplBase
- {
- private readonly IUnityContainer _unityContainer;
- public UnityServiceLocatorAdapter(IUnityContainer unityContainer)
- {
- this._unityContainer = unityContainer;
- }
- protected override object DoGetInstance(Type serviceType, string key)
- {
- return this._unityContainer.Resolve(serviceType, key);
- }
- protected override IEnumerable<object> DoGetAllInstances(Type serviceType)
- {
- return this._unityContainer.ResolveAll(serviceType);
- }
- }
- }

Recent Comments