【问题标题】:Mock Setup Exception for valid setup有效设置的模拟设置异常
【发布时间】:2016-03-07 18:25:08
【问题描述】:

我有以下类结构:

public class MyObj
{
    public int Number;
}
public interface IService
{
    int ProcessInt(MyObj obj);
}
public class Service : IService
{
    public int ProcessInt(MyObj myObj)
    {
        return myObj.Number;
    }
}

然后是消费者类

public class Class1
{
    public void Run(IService s)
    {
        var obj = new MyObj {Number = 1};
        Console.WriteLine(s.ProcessInt(obj));
    }
}

然后是单元测试

[TestFixture]
public class MyTest
{

    private readonly Mock<IService> _service = new Mock<IService>(MockBehavior.Strict);
    private readonly Class1 _sut = new Class1();

    [SetUp]
    public void SetUp()
    {
        var obj = new MyObj {Number = 1};
        _service.Setup(x => x.ProcessInt(obj)).Returns(1);
    }

    [Test]
    public void TestClass1()
    {
        _sut.Run(_service.Object);
    }
}

我遇到的问题是,当我运行单元测试时,我得到“Moq.MockException : IService.ProcessInt(MoqStuff.MyObj) 调用失败,模拟行为严格。模拟上的所有调用都必须有相应的设置。“这很奇怪,因为我有那个输入的设置。

这是 Moq 框架的预期行为吗?有什么办法可以解决吗?

谢谢

【问题讨论】:

    标签: c# unit-testing nunit moq


    【解决方案1】:

    您的 SetUp 方法中有此代码:

    var obj = new MyObj {Number = 1};
    _service.Setup(x => x.ProcessInt(obj)).Returns(1);
    

    在这里你设置期望,ProcessInt 被这个特定对象 obj 调用。

    但是,在您的方法 Run 中,您创建了另一个对象:

    var obj = new MyObj {Number = 1};
    

    虽然属性值相同,但该对象与您在SetUp 方法中创建的对象完全不同。这就是为什么您会因缺少设置而出现异常的原因。

    您可以改为使用It.IsAny 为任何输入参数设置服务:

    [SetUp]
    public void SetUp()
    {
        _service.Setup(x => x.ProcessInt(It.IsAny<MyObj>())).Returns(1);
    }
    

    此设置适用于任何参数值。

    或者如果您只想根据某些条件进行匹配,您可以使用It.Is

    [SetUp]
    public void SetUp()
    {
        // setup only for cases where obj.Number == 1
        _service
            .Setup(x => x.ProcessInt(It.Is<MyObj>(o => o.Number == 1 )))
            .Returns(1);
    
        // setup only for cases where obj.Number == 2
        _service
            .Setup(x => x.ProcessInt(It.Is<MyObj>(o => o.Number == 2 )))
            .Returns(2);
    }
    

    【讨论】:

    • 我不能这样做,因为假设我有一个包含 10 个元素的列表,并且行为是对于其中一些元素我需要一个结果,而对于其他元素我需要另一个结果。所以我需要根据对象内部的值以某种方式模拟。
    • @kord 然后你可以使用It.Is。我用详细信息更新了我的答案
    猜你喜欢
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 2010-12-26
    • 1970-01-01
    • 2020-01-01
    • 1970-01-01
    相关资源
    最近更新 更多