C# 如何在模拟中为不同的输入返回不同的值? [TestClass] 公共类UnitTest1 { [测试方法] 公共void TestMethod1() { var o1=新的XmlDocument(); var o2=新的XmlDocument(); var mock=new mock(); Setup(m=>m.TestMethod(o1)).Returns(1); Setup(m=>m.TestMethod(o2)).Returns(2); AreEqual(1,mock.Object.TestMethod(o1)); AreEqual(2,mock.Object.TestMethod(o2)); } } 公共接口ITestInterface { int测试方法(对象输入); }

C# 如何在模拟中为不同的输入返回不同的值? [TestClass] 公共类UnitTest1 { [测试方法] 公共void TestMethod1() { var o1=新的XmlDocument(); var o2=新的XmlDocument(); var mock=new mock(); Setup(m=>m.TestMethod(o1)).Returns(1); Setup(m=>m.TestMethod(o2)).Returns(2); AreEqual(1,mock.Object.TestMethod(o1)); AreEqual(2,mock.Object.TestMethod(o2)); } } 公共接口ITestInterface { int测试方法(对象输入); },c#,mocking,moq,C#,Mocking,Moq,为什么mock总是返回第二个值?如果我将XmlDocument切换到其他任何东西(对象、StringBuilder等),它将按预期工作。我会假设它也会按您的预期工作,但我也会得到相同的结果。但是,如果您改为按以下方式进行设置,它将按照您的要求工作 [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { var o1 = new XmlDocument();

为什么mock总是返回第二个值?如果我将XmlDocument切换到其他任何东西(对象、StringBuilder等),它将按预期工作。

我会假设它也会按您的预期工作,但我也会得到相同的结果。但是,如果您改为按以下方式进行设置,它将按照您的要求工作

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

如果将两个
InnerXml
值都设置为相同的字符串,它甚至可以工作。这真是个谜,我一直无法解释。

我运行了你的代码,遇到了同样的问题。按照您发布的方式运行代码在第一次断言时失败,消息为:Assert.AreEqual failed。预期:。实际值:。。当我将o1和o2更改为
object
而不是
XmlDocument
时,它按预期工作

奇怪的是,将2个设置行更改为以下将导致生成正确的结果:

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)}");
mock.Setup(m=>m.TestMethod(It.Is(x=>x==o1)).Returns(1);
Setup(m=>m.TestMethod(It.Is(x=>x==o2))).Returns(2);

这很奇怪,因为我相信你的两条安装线应该和我的完全一样,但是我的在这种情况下工作正常,而你的不正常。我假设有一个我不知道的差异,或者是Moq中有一个错误导致了这一点。

(我删除了我的第一条评论,因为它是错误的。)很奇怪,原始代码不工作,因为
System.Xml.XmlDocument
没有覆盖
Equals
(它的基类也没有)并且不实现(直接或间接)
IEquatable
。那么,为什么它与
StringBuilder
的处理方式不同呢?@JeppeStigNielsen我曾认为Moq可能是想通过查看不包含xmlcodem的XML来提供帮助。我认为有一个很好的论点,即即使引用不同,如果XML相同,从逻辑上讲,它们也是相同的对象。但显然,将InnerXml设置为任意值都可以使一切正常工作。感觉好像某处有个虫子。这和安迪的答案是一样的。即使您将
It.Is(x=>x==o1))
object
而不是
XmlDocument
一起使用,这也会起作用(Andy的也是如此)。无论如何都会使用相同的重载
操作符==
(预定义的
bool操作符==(对象,对象)
,它只是引用相等)。
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)}");
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);