【问题标题】:How to set the value of an out parameter Mocked in Moq within the "Return"?如何在“返回”中设置 Moq 中模拟的输出参数的值?
【发布时间】:2018-06-04 17:15:47
【问题描述】:

我在配置起订量时遇到了一些问题。

我有一个带有 out 参数的方法的模型。这个 out 参数确实有用,我需要根据收到的参数填充一些有意义的值。

目前,我无法做到这一点,可以吗?怎么样?

这是我目前的状态:

Mock<IMyMock> _mock = new Mock<IMyMock>();
bool someFlag= false;
_mock.Setup(m=>m.GetSomething(It.IsAny<DateTime>(), It.IsAny<DateTime>(), out someFlag))
     .Returns((DateTime start, DateTime end, bool someFlagInternal)=>{
        IEnumerable<SomeOtherClass> otherClasses = GenerateMockedData(start, end);
        //Assign something to someFlag, depending on start and end
        someFlag=true;//This has no effects
     }) ;
new SomeController(_mock.Object);

在我的SomeController 中,在特定方法上,我的真实非模拟代码调用它:

public class SomeController{}
    private IMyMock _someObjectThatWeDontKnowIsAMock;
    public SomeController(IMyMock someObjectThatWeDontKnowIsAMock) {
        _someObjectThatWeDontKnowIsAMock= someObjectThatWeDontKnowIsAMock;
    }

    private void ComputeNext() {
        Tuple<DateTime, DateTime> times = ComputeNextTimes();
        bool hasOverlap;
        IEnumerable<SomeOtherClass> otherClassesInstances = _someObjectThatWeDontKnowIsAMock.GenerateMockedData(times.Data1, times.Data2, out hasOverlap);
        if(hasOverlap) {
            //...
        }
    }
}

每次我调用我的模拟,它似乎返回someFlag 的第一个值,即使它是我修改的静态字段。

【问题讨论】:

    标签: c# .net unit-testing mocking moq


    【解决方案1】:

    您遇到的问题是因为设置中out参数的实例与执行测试时实际使用的实例不同。

    取自 Moq Quickstart 文档

    带有ref / out 参数的方法的回调是可能的,但需要一些工作(以及 Moq 4.8 或更高版本)

    创建一个委托来处理模拟调用。

     delegate IEnumerable<SomeOtherClass> GetSomethingCallback(DateTime start, DateTime end, out bool someFlag);
    

    在设置中使用It.Ref&lt;Bar&gt;.IsAny 作为out 参数并在Returns 表达式中使用委托。

    mock
        .Setup(_ => _.GetSomething(It.IsAny<DateTime>(), It.IsAny<DateTime>(), out It.Ref<bool>.IsAny))
        .Returns(new GetSomethingCallback((DateTime start, DateTime end, out bool someFlag) => {
            IEnumerable<SomeOtherClass> otherClasses = GenerateMockedData(start, end);
            //Assign something to someFlag, depending on start and end
            someFlag = true;
            return otherClasses;
        }));
    

    It.Ref&lt;bool&gt;.IsAny 指示返回委托与传递给模拟成员的实际对象的实例引用进行交互。

    【讨论】:

    • 我使用的是 4.7.x,但我无法使用它。现在有了 4.8 和您的解决方案,它就像一个魅力!非常感谢
    猜你喜欢
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    • 1970-01-01
    • 2022-06-30
    • 2015-12-14
    相关资源
    最近更新 更多