Как вернуть разные значения для разных входных данных в макете? - PullRequest
0 голосов
/ 10 сентября 2018
[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        var o1 = new XmlDocument();
        var o2 = new XmlDocument();

        var mock = new Mock<ITestInterface>();
        mock.Setup(m => m.TestMethod(o1)).Returns(1);
        mock.Setup(m => m.TestMethod(o2)).Returns(2);

        Assert.AreEqual(1, mock.Object.TestMethod(o1));
        Assert.AreEqual(2, mock.Object.TestMethod(o2));
    }
}

public interface ITestInterface
{
    int TestMethod(object input);
}

Почему mock всегда возвращает второе значение? Если бы я переключил XmlDocument на что-либо еще (объект, StringBuilder и т. Д.), Он бы работал как положено.

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Я запустил ваш код и столкнулся с той же проблемой.Выполнение вашего кода в точности так, как вы опубликовали, завершается неудачно на первом Assert с Message: Assert.AreEqual failed. Expected:<1>. Actual:<2>..Когда я изменяю o1 и o2 на object вместо XmlDocument, это работает должным образом.

Как ни странно, изменение двух строк настройки на следующее приведет к получению правильных результатов:

mock.Setup(m => m.TestMethod(It.Is<XmlDocument>(x => x == o1))).Returns(1);
mock.Setup(m => m.TestMethod(It.Is<XmlDocument>(x => x == o2))).Returns(2);

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

0 голосов
/ 11 сентября 2018

Я бы предположил, что это будет работать так, как вы ожидали, но я также получаю те же результаты.Однако если вы вместо этого выполните настройку, как показано ниже, она будет работать так, как вы хотите.

mock.Setup(m => m.TestMethod(It.Is<XmlDocument>(y => ReferenceEquals(o1, y)))).Returns(1);
mock.Setup(m => m.TestMethod(It.Is<XmlDocument>(y => ReferenceEquals(o2, y)))).Returns(2);

Что-то еще, что я заметил, когда я проверял далее, что если вы установите InnerXml, все будет работать как выПервоначальная настройка.

var doc1 = new XmlDocument { InnerXml = "<root1 />" };
var doc2 = new XmlDocument { InnerXml = "<root2 />" };;
mock.Setup(x => x.TestMethod(doc1)).Returns(1);
mock.Setup(x => x.TestMethod(doc2)).Returns(2);

Console.WriteLine($"{mock.Object.TestMethod(doc1)}");
Console.WriteLine($"{mock.Object.TestMethod(doc2)}");

Это работает даже в том случае, если оба значения InnerXml установлены в одинаковые строки.Это действительно загадка, и я не смог ее объяснить.

...