我正在我的.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);
测试控制器代码:
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 的最小起订量页面中的解决方案,但没有结果,这里是 ref => 最小起订量快速入门
返回 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
需要最小起订量 4.8 或更高版本
参考最小起订量快速入门:匹配参数
对于旧版本,应从链接的文档示例中注明 tt
// 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无法在不对测试代码进行一些修改的情况下提供所需的行为