J4N*_*J4N 3 .net c# unit-testing moq mocking
我在配置 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);
Run Code Online (Sandbox Code Playgroud)
在我的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) {
//...
}
}
}
Run Code Online (Sandbox Code Playgroud)
每次我调用我的模拟时,它似乎都会返回 的第一个值someFlag,即使它是我修改的静态字段。
您遇到的问题是因为设置中 out 参数的实例与执行测试时实际使用的实例不同。
取自Moq Quickstart文档
带有
ref/out参数的方法的回调是可能的,但需要一些工作(以及 Moq 4.8 或更高版本)
创建一个委托来处理模拟调用。
delegate IEnumerable<SomeOtherClass> GetSomethingCallback(DateTime start, DateTime end, out bool someFlag);
Run Code Online (Sandbox Code Playgroud)
在设置使用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;
}));
Run Code Online (Sandbox Code Playgroud)
的It.Ref<bool>.IsAny指示返回给委托与该通入嘲笑构件的实际对象的实例参考交互。