How to use Moq to satisfy a MEF import dependency for unit testing?

.net, c#, mef, moq, unit-testing

Solution

You don't need to Mock the `Lazy<T,TMetadta>`. It is flexible enough to work with your test. Instead, Mock the `IWindowTypeInfo`

[TestMethod]
public void GetIDTest()
{
    var windowTypeInfoMock = new Mock<IWindowTypeInfo>();
    windowTypeInfoMock.Setup(foo => foo.Name).Returns("Data");
    windowTypeInfoMock.Setup(foo => foo.UniqueID).Returns("someString");
    var lazyWindow =
         new Lazy<IWindowType, IWindowTypeInfo>(windowTypeInfoMock.Object);

    var WindowTypesList = new List<Lazy<IWindowType, IWindowTypeInfo>>();
    WindowTypesList.Add(lazyWindow);

    var a = new A();
    a.WindowTypes = WindowTypesList;
    var InfoMock = new Mock<Information>();
    InfoMock.Setup(foo => foo.TargetName).Returns("Data");

    string expected = "someString";
    string actual;
    actual = a.GetIdentifierForItem(InfoMock.Object);
    Assert.AreEqual(expected, actual);
}

Your test passes on my machine with only small modifications, you do not need to use a composition container for this test.

Problem

This is my interface ``` public interface IWork { string GetIdentifierForItem(Information information); } ``` and my class ``` public class A : IWork { [ImportMany] public IEnumerable<Lazy<IWindowType, IWindowTypeInfo>> WindowTypes { get; set; } public string GetIdentifierForItem(Information information) { string identifier = null; string name = information.TargetName; // Iterating through the Windowtypes // searching the 'Name' and then return its ID foreach (var windowType in WindowTypes) { if (name == windowType.Metadata.Name) { identifier = windowType.Metadata.UniqueID; break; } } return identifier; } } ``` Problem : I want to unit test the method `GetIdentifierForItem` Here is what I tried doing to solve it - (1)Create a mock Lazy and set the values that it needs to return on property gets `var windowMock = new Mock<Lazy<IWindowType, IWindowTypeInfo>>(); windowMock.Setup(foo => foo.Metadata.Name).Returns("Data"); windowMock.Setup(foo => foo.Metadata.UniqueID).Returns("someString");` (2)Create a window type list and the above mocked object and then set it to the created A object ``` var WindowTypesList = new List<IWindowType, IWindowTypeInfo>>(); WindowTypesList.Add(windowMock.Object); A a = new A(); a.WindowTypes = WindowTypesList; ``` (3) Create the information mock ``` var InfoMock = new Mock<Information>(); InfoMock.Setup(foo => foo.TargetName).Returns("Data"); ``` To put all of the above together as the unit test ``` [TestMethod] public void GetIDTest() { var windowMock = new Mock<Lazy<IWindowType, IWindowTypeInfo>>(); windowMock.Setup(foo => foo.Metadata.Name).Returns("Data"); windowMock.Setup(foo => foo.Metadata.UniqueID).Returns("someString"); var WindowTypesList = new List<Lazy<IWindowType, IWindowTypeInfo>>(); WindowTypesList.Add(windowMock.Object); A a = new A(); a.WindowTypes = WindowTypesList; var InfoMock = new Mock<Information>(); InfoMock.Setup(foo => foo.TargetName).Returns("Data"); string expected = "someString"; // TODO: Initialize to an appropriate value string actual; actual = a.GetIdentifierForItem(InfoMock.Object); Assert.AreEqual(expected, actual); } ``` This unit test fails to execute and throws an exception 'TargetInvocationException' and veiwing the detail, it looks like I am doing something that I should not be doing. But I am not sure how do it other way. I have read some of the links in the Quickstart guide of Moq. I know I am missing something. Can you help me by guiding how to unit test this?

Original source