首页 > 解决方案 > 如何在“返回”中设置 Moq 中模拟的输出参数的值?

问题描述

我在配置 Moq 时遇到了一些麻烦。

我有一个带有 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#.netunit-testingmockingmoq

解决方案


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

取自Moq 快速入门文档

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

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

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

在设置中使用It.Ref<Bar>.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<bool>.IsAny成员的实际对象的实例引用进行交互。


推荐阅读