使用ref参数模拟一个方法以返回特定值

时间:2018-04-23 07:18:55

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

我在我的.NET项目中使用Moq进行单元测试我的代码和 我正在尝试使用 ref 参数模拟我的一个服务并返回特定结果。

服务代码:

public bool CallServiceFunctionTest(IList<TestObject> test, ref IList<TestObjectErrors> errors)
{
    //...
    return !errors.Any();
}

控制器代码:

var test = _dataUnitOfWork.TestRepository.GetTest(id);
IList<TestObjectErrors> errors = new List<TestObjectErrors>();
var testingResponse = service.CallServiceFunctionTest(test, errors);

TestController代码:

IList<TestObject> fakeObjects = new List<TestObject>()
{
    new TestObject(){Id = 1 , Name = 'Test'}
};

_dataUnitOfWork.Setup(x => x.TestRepository.GetTest(1, null)).Returns(Task.FromResult(fakeObjects));
IList<TestObjectErrors> errors = new It.IsAny<IList<TestObjectErrors>>();
_service.Setup(x => x.CallServiceFunctionTest(fakeObjects, ref errors)).Returns(true);

由于GitHub moq页面,还尝试使用与真实调用相同的实例:

IList<TestObjectErrors> errors = new List<TestObjectErrors>();
_service.Setup(x => x.CallServiceFunctionTest(fakeObjects, ref errors)).Returns(true);

我阅读了一些解决方案并尝试使用回调,没有特定的参数,但我仍然没有得到'真实'的结果。我确信我错过了一些东西,但我不知道是什么。我也尝试了解决方案在GitHub的moq页面中但没有结果,这里是ref =&gt; Moq Quickstart

1 个答案:

答案 0 :(得分:1)

模拟返回false可能表示模拟上设置的参数与执行测试时实际传递的参数不匹配。

使用It.IsAny<T>()It.Ref<T>.IsAny参数匹配器放松模拟服务的期望

_service
    .Setup(_ => _.CallServiceFunctionTest(It.IsAny<IList<TestObject>>(), ref It.Ref<IList<TestObjectErrors>>.Any))
    .Returns(true);

请注意,It.Ref<T>.IsAny需要Moq 4.8或更高版本

参考Moq Quickstart: Matching Arguments

对于旧版本,应该从链接的文档示例

中注明
// ref arguments
var instance = new Bar();
// Only matches if the ref argument to the invocation is the same instance
mock.Setup(foo => foo.Submit(ref instance)).Returns(true);

只有在执行测试时使用的实际实例相同时,ref才会匹配。

但是在示例中显示的控制器代码中,您正在修改错误,这意味着测试中的实例将与模拟中的实例不同。

因此,如果没有对测试中的代码进行某些修改,看起来旧版本的Moq无法提供所需的行为