【问题标题】:How to use Moq to satisfy a MEF import dependency for unit testing?如何使用 Moq 来满足单元测试的 MEF 导入依赖项?
【发布时间】:2012-04-19 06:20:31
【问题描述】:

这是我的界面

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)创建一个模拟 Lazy 并设置它需要在属性获取上返回的值

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

(2)创建一个窗口类型列表和上面的mocked对象,然后将其设置为创建的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 快速入门指南中的一些链接。我知道我错过了一些东西。您能通过指导如何进行单元测试来帮助我吗?

【问题讨论】:

    标签: c# .net unit-testing moq mef


    【解决方案1】:

    这就是在设置模拟之后可以完成的方式

    1) 创建一个包含导入的 CompositionContainer。

    2) 将 Mocks 添加到容器中。

    container.ComposeExportedValue(mock.Object);
    

    3) 创建测试类的实例

    4) 为导入编写模拟

    container.ComposeParts(instance);
    

    【讨论】:

      【解决方案2】:

      您无需模拟Lazy&lt;T,TMetadta&gt;。它足够灵活,可以处理您的测试。相反,模拟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);
      }
      

      你的测试在我的机器上通过了,只做了小的修改,你不需要为这个测试使用组合容器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-20
        • 2018-06-15
        • 2020-04-29
        相关资源
        最近更新 更多