[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);
}
为什么模拟总是返回第二个值?如果我将XmlDocument切换到其他任何对象(对象,StringBuilder等),它将按预期工作。
答案 0 :(得分:3)
我以为它也可以按照您的预期工作,但我也得到相同的结果。但是,如果改为按以下方式进行设置,则它将按您希望的那样工作。
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
的值设置为相同的字符串,它甚至可以工作。这确实是个谜,我一直无法解释。
答案 1 :(得分:1)
我运行了您的代码,并遇到了同样的问题。在第一个使用Message: Assert.AreEqual failed. Expected:<1>. Actual:<2>.
的断言中,准确地运行代码的发布方式失败。当我将o1和o2更改为object
而不是XmlDocument
时,它按预期工作。
奇怪的是,将2条设置行更改为以下内容将使其产生正确的结果:
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);
这很奇怪,因为我认为您的2条设置行的行为应与我的完全一样,但是在这种情况下,我的设置行却可以正常工作,而您的行却不行。我假设存在我不知道的差异,或者Moq存在一个导致此错误的错误。