Monday, December 10, 2012

Testing non exported classes which rely on MEF injection

Testing non exported classes which rely on MEF injection

I am using MEF to compose my objects together and have ran into a problem when testing some classes which are not exported to the MEF container but rely on having object instances injected into property setters by MEF.

For example consider the following two view models

public class ViewModelA {     [Import]     internal IAdmin AdminService     {         get;         private set;     }      public ViewModelA()     {         CompositionInitializer.SatisfyImports(this);     }      //constructor for testing     internal ViewModelA(IAdmin adminService)     {         this.AdminService = adminService;     }      public void DoSomething()     {         this.AdminService.SetCurrentWindow(new ViewModelB());     } }   public class ViewModelB  {     [Import]     internal IAdmin AdminService     {         get;         private set;     }      [Import]     internal IAnotherService AnotherServiceService     {         get;         private set;     }      public ViewModelB()     {         CompositionInitializer.SatisfyImports(this);     }      public void DoAnotherThing()     {         //Does something with the properties injected via MEF     }  } 

These classes are not exported to the MEF container so I rely on calling CompositionInitializer.SatisfyImports(this) to force an import of the dependencies.

I want to create a test for ViewModelA that checks a call to DoSomething results in the IAdmin.SetCurrentWindow method being called once with an instance of ViewModelB. In order to satisfy this I created a constructor overload for ViewModelA which takes an IAdmin as an argument, I also created the following test utilising Moq and the Silverlight Unit Testing Framework.

    [TestMethod]     public void DoSomethingStandard_CallsSetCurrentWindowWithViewModelB()     {         var adminServiceMock = new Mock<IAdmin>();         var vmA = new ViewModelA(adminServiceMock.Object);         vmA.DoSomething();         adminServiceMock.Verify(ad => ad.SetCurrentWindow(It.IsAny<ViewModelB>()), Times.Exactly((1)));     } 

My problem is that when the test runs the call to ViewModelA.DoSomething instantiates a ViewModelB which in turn throws a

System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

This is because the ViewModelB constructor calls CompositionInitializer.SatisfyImports(this) but in my test project there are no MEF containers set up.

Are there any thoughts on how it would be best to test such a scenario? Or how the code could be restructured to make it testable?

Answers & Comments...




No comments:

Post a Comment

Send us your comment related to the topic mentioned on the blog