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

瘦欲@ 提交于 2019-12-04 01:32:32

问题


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?


回答1:


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.




回答2:


This is how it may be done, after setting up the mocks

1) Creating a CompositionContainer, that holds the imports.

2) Adding Mocks to the container.

container.ComposeExportedValue(mock.Object);

3) Create an instance of tested class

4) Compose mocks to the import

container.ComposeParts(instance);


来源:https://stackoverflow.com/questions/10222654/how-to-use-moq-to-satisfy-a-mef-import-dependency-for-unit-testing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!