Вопрос по .net, c# – Как использовать Moq для удовлетворения зависимости импорта MEF для модульного тестирования?

4

Это мой интерфейс

<code>public interface IWork
{
    string GetIdentifierForItem(Information information);
}
</code>

и мой класс

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

Проблема: Я хочу провести модульное тестирование метода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) Создайте список типов окон и вышеуказанный макет объекта, а затем установите его для созданного объекта A

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

(3) Создать информационный макет

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

Чтобы собрать все вышеперечисленное вместе в качестве модульного теста

<code>[TestMethod]
public void GetIDTest()
{
    var windowMock = new Mock<Lazy<IWindowType, IWindowTypeInfo>>();
    windowMock.Setup(foo => foo.Metadata.Name).Returns("Data");
    windowMock.Setup(foo => f,oo.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);

}
</code>

Этот модульный тест не выполняется и выдает исключение «TargetInvocationException», и, учитывая детали, похоже, что я делаю то, чего не должен делать.

Но я не уверен, как это сделать иначе. Я прочитал некоторые ссылки в руководстве по быстрому запуску Moq. Я знаю, что что-то упустил. Можете ли вы помочь мне, руководствуясь, как провести модульное тестирование этого?

Ваш Ответ

2   ответа
6

1) Создание CompositionContainer, который содержит импорт.

2) Добавление макетов в контейнер.

container.ComposeExportedValue(mock.Object);

3) Создать экземпляр тестируемого класса

4) Составить макеты для импорта

container.ComposeParts(instance);
2

Тебе не надо издеваться над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);
}

Ваше тестирование проходит на моей машине только с небольшими изменениями, вам не нужно использовать контейнер композиции для этого теста.

Похожие вопросы