Click here to Skip to main content
13,898,662 members
Click here to Skip to main content
Add your own
alternative version


8 bookmarked
Posted 9 Dec 2013
Licenced CPOL

Unit testing imports in MEF - Loving that lazy interface

, 9 Dec 2013
Rate this:
Please Sign up or sign in to vote.
While we are all familiar with testing standard interface implementations, actually testing Lazy imports can be trickier if you don't follow this trick.


Okay, it's well known that I love MEF with all it's composition-y goodies, and how I strive to write code to interfaces. As someone who believes that unit testing should be at the forefront of every developers mind, I spend a lot of time writing code that uses mocks of interfaces, but it seems to me that the process of actually testing MEFfed interfaces isn't immediately obvious to anyone who's new to the technology. 


While we can mock public imports, and invoking the composition can seem counter-intuitive, I have a preference to keep my import interfaces private.  If you're happy to expose your composition properties, then you could just mock and add your interfaces as necessary. If, like me, you want to hide the implementation details of your dependency injection so that someone doesn't accidentally do something to break your composition, this technique is for you. 

The setup

For this example, we're going to use three highly contrived interfaces; IAnimal, IDog and ICat.

public interface IAnimal
  void MakeNoise();

public interface IDog : IAnimal
  void ChaseMailman();

public interface ICat : IAnimal
  void PlayWithYarn();

As I said, this is a highly contrived set of interfaces. Now, the code Iwewant to use here allows the application to retrieve either one of these three interfaces, using MEF to populate the application with a list of classes that implement these interfaces.

A bit of class   

For the purposes of this tip, I'm going to shortcircuit the whole TDD approach I like to work with, and show you the end product of this class: 

using System;
using System.ComponentModel.Composition;

public interface IAnimalManager
  IEnumerable<Lazy<IAnimal>> _animals { get; set; }
public class AnimalManager : IAnimalManager
  private IEnumerable<Lazy<IAnimal>> _animals { get; set; }

  public T GetAnimal<T>() where T : IAnimal
    IAnimal animal = _animals.SingleOrDefault(pet => pet.Value is T);
    if (animal == null) return default(T);
    return (T)animal.Value;

As we can see, this isn't a particularly complicated class, but it does rely heavily on MEF "filling in the blanks" so to speak. Specifically, it relies on things like MEF being able to compose a private Lazy property with all of the items it imports that matches the definition. 

Testing this bad boy

So, how exactly do we test this code? There are several things in here that could make the testing problematic. First of all, we have made the import property private - while we could, of course, have made the property public, this would have been a bad design decision because we are trying to keep our code self-contained. Also, we are using an enumerable lazy property - mocking this can be a bit of a pain. Also, we wouldn't be testing the behaviour of the system in the way we'd expect it to be used - this potentially defers a fair bit of pain into the integration testing phase. where it's a lot harder and more expensive to fix.

Fortunately, using MEF inside our test code is actually very, very simple. What we do is mimic the behaviour of MEF and do some composition "magic". Before we look at what the code is doing, let's actually see what our test looks like 

public void AnimalManager_GetDog_RetrievesDog()
  // Mock the IDog interface for use in the composition part
  Mock<IDog> dog = new Mock<IDog>(); 

  // Create the concrete instance to compose into.
  AnimalManager animalManager = new AnimalManager();
  CompositionContainer container = new CompositionContainer();

  // Create an export composition of the mocked IDog interface

  // Actually compose the concrete animal manager instance.

The first thing that we do is mock the IDog interface for use inside our import in the instance of the AnimalManager class that we have created. The clever bit is actually the next part; create an instance of the MEF CompositionContainer, and call ComposeExportedValue on our mocked IDog interface. Finally, we call ComposeParts passing in the concrete instance of the AnimalManager class. At this point, our class is now a properly composed class, and our test will run and behave itself. 

Final thoughts

I hope this has given you a flavour of how easy it can be testing a testable MEF application. Our MEFfed object isn't exposing it's properties to the world for testing purposes, so we can keep our compositions nice and tightly focussed. If we build an object that has multiple imports, we shouldn't worry about handling the interfaces we don't need to test a particular method - our tests should only fill in those parts of the composition container that we absolutely need for the test, so our tests shouldn't get too big.

Go forth, MEF and be fruitful. 


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Pete O'Hanlon
United Kingdom United Kingdom
A developer for over 30 years, I've been lucky enough to write articles and applications for Code Project as well as the Intel Ultimate Coder - Going Perceptual challenge. I live in the North East of England with 2 wonderful daughters and a wonderful wife.

I am not the Stig, but I do wish I had Lotus Tuned Suspension.

You may also be interested in...

Comments and Discussions

Questionnice example Pin
Vick Blau17-Apr-14 5:53
memberVick Blau17-Apr-14 5:53 
QuestionNice one. Short, but sweet! Pin
SteveTheThread9-Dec-13 21:54
memberSteveTheThread9-Dec-13 21:54 
AnswerRe: Nice one. Short, but sweet! Pin
Pete O'Hanlon9-Dec-13 22:47
protectorPete O'Hanlon9-Dec-13 22:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01 | 2.8.190306.1 | Last Updated 9 Dec 2013
Article Copyright 2013 by Pete O'Hanlon
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid