如何使用 Moq 满足单元测试的 MEF 导入依赖项

本文关键字:MEF 导入 依赖 单元测试 何使用 Moq 满足 | 更新日期: 2023-09-27 18:31:48

这是我的界面

public interface IWork
{
    string GetIdentifierForItem(Information information);
}

和我的班级

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;
}
}

问题:我想对方法进行单元测试GetIdentifierForItem

这是我试图解决它的方法 -

(1)创建一个模拟懒惰,并设置它在属性获取时需要返回的值

var windowMock = new Mock<Lazy<IWindowType, IWindowTypeInfo>>(); windowMock.Setup(foo => foo.Metadata.Name).Returns("Data"); windowMock.Setup(foo => foo.Metadata.UniqueID).Returns("someString");

(2)创建窗口类型列表和上述模拟对象,然后将其设置为创建的A对象

var WindowTypesList = new List<IWindowType, IWindowTypeInfo>>();
WindowTypesList.Add(windowMock.Object);
A a = new A();
a.WindowTypes = WindowTypesList;

(3) 创建信息模拟

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

将上述所有内容放在一起作为单元测试

[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);
}

这个单元测试无法执行并抛出异常"TargetInvocationException"并掩盖细节,看起来我正在做一些我不应该做的事情。

但我不确定如何以其他方式做到这一点。我已经阅读了最小起订量快速入门指南中的一些链接。我知道我错过了什么。你能指导我如何对此进行单元测试吗?

如何使用 Moq 满足单元测试的 MEF 导入依赖项

这是

在设置模拟后可以完成的

1) 创建一个包含导入的合成容器。

2) 将模拟添加到容器中。

container.ComposeExportedValue(mock.Object);

3) 创建测试类的实例

4)为导入编写模拟

container.ComposeParts(instance);

你不需要嘲笑Lazy<T,TMetadta>。 它足够灵活,可以与您的测试配合使用。 相反,嘲笑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);
}

您的测试在我的机器上通过,只需进行少量修改,您无需为此测试使用组合容器。