xUnit下Moq设置多参数GetReport方法返回null而非预期对象问题
问题原因
核心是Moq的方法重载匹配和参数匹配规则没有命中你设置的Setup,所以返回默认值null:
- dynamic类型参数引用不匹配:Moq默认对引用类型参数做实例匹配,你Setup时传入的
siteWithStatusDataViewMoq实例,和业务代码实际调用GetReport时传入的第四个参数如果不是同一个引用对象,哪怕所有属性值完全一致,也会匹配失败。 - 参数值不匹配:Setup时填写的int参数值、string类型的
SiteSearchStatus值,和业务代码实际调用时传入的对应参数值不一致,导致匹配失败。 - 重载匹配错误:你Setup的是
(int,bool,string,dynamic)的重载,但业务代码实际调用的是(int,bool,string,Exception)的另一个4参数重载,自然不会命中你写的Setup。
解决方案
- 使用参数匹配符放宽或精准校验规则
如果不需要严格校验第四个dynamic参数的实例,直接用It.IsAny<dynamic>匹配,或者按属性值做匹配,示例代码:
queryResultHelperMoq.Setup(x => x.GetReport( It.Is<int>(count => count == (siteWithStatusDataViewMoq == null ? 0 : 1)), false, It.Is<string>(msg => msg == SiteSearchStatus), // 可根据需求选择任意匹配或属性匹配 It.IsAny<dynamic>() // 要校验属性的话用:It.Is<dynamic>(d => d.Id == siteWithStatusDataViewMoq.Id) )).Returns(queryResultSummaryMoq);
- 验证实际调用的重载是否符合预期
在测试方法的业务逻辑执行完成后,添加Verify代码校验调用是否命中,排查是否调错了重载:
// 校验你Setup的重载是否被调用过一次 queryResultHelperMoq.Verify(x => x.GetReport( It.IsAny<int>(), It.IsAny<bool>(), It.IsAny<string>(), It.IsAny<dynamic>() ), Times.Once, "目标重载未被调用,请检查业务代码的参数类型是否正确");
如果上述Verify抛出异常,说明业务代码实际调用的是其他重载,对应调整Setup的重载即可。
内容的提问来源于stack exchange,提问作者K.Z
相关产品推荐
相关产品推荐

