How to set the value of an out parameter Mocked in Moq within the "Return"?

时间:2018-06-04 17:15:48

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

I've some trouble while configuring my Moq.

I've a mockup with a method that has out parameter. This out parameter is really used, and I need to populate it with some meaningful value depending on the parameter I receive.

Currently, I've been unable to do this, is it possible? How?

Here is my current status:

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

In my SomeController, on a specific method, my real-non-mocked code calls it:

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) {
            //...
        }
    }
}

Every time I call my mock, it seems to returns the first value of someFlag, even if it is a static field that I modify.

1 个答案:

答案 0 :(得分:2)

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

取自Moq Quickstart文档

  

可以使用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指示返回委托与传递给模拟成员的实际对象的实例引用进行交互。