C# xUnit Moq单元测试配置Returns(true)后模拟服务仍返回false如何解决
问题原因
核心问题是Moq的参数匹配失败:你Setup方法时传入的参数,和控制器实际运行时调用该方法传入的参数不匹配,因此触发不了你设置的返回值,Moq就返回了默认值false。
具体不匹配点如下:
- 第二个
MinRequiredDataVersion类型的参数完全不匹配:控制器运行时会基于你配置的mockMinRequiredDatabaseVersion返回的888/888/888属性,new一个全新的MinRequiredDataVersion对象;而你Setup时传入的是Fixture中预定义的、属性为5/5/5的mockMinRequiredDataVersion.Object,两个实例不同、属性值也不一致。 - 如果你使用的
VwCurrentVersionInfo和MinRequiredDataVersion是未重写Equals方法的引用类型,Moq默认按引用匹配参数,就算值相同、不是同一个实例也会匹配失败。
调整方案
方案1:按属性值匹配参数(推荐,最严谨)
修改你测试方法中hasWebSolutionTheRightDatabase的Setup代码,用It.Is<>匹配符合预期属性值的任意实例即可:
// 替换原有的hasWebSolutionTheRightDatabase Setup代码 fixture.mockConfigService.Setup(x => x.hasWebSolutionTheRightDatabase( // 匹配第一个参数:属性为988/988/988的VwCurrentVersionInfo实例 It.Is<VwCurrentVersionInfo>(v => v.MajorVersion == 988 && v.MinorVersion == 988 && v.BuildNumber == 988), // 匹配第二个参数:属性为888/888/888的MinRequiredDataVersion实例 It.Is<MinRequiredDataVersion>(m => m.MajorVersion == 888 && m.MinorVersion == 888 && m.BuildNumber == 888) )).Returns(true);
方案2:匹配任意参数(快速验证用,不推荐用于正式测试)
如果不需要校验传入参数的正确性,只想强制让方法返回true,可以用It.IsAny<>匹配任意参数:
fixture.mockConfigService.Setup(x => x.hasWebSolutionTheRightDatabase( It.IsAny<VwCurrentVersionInfo>(), It.IsAny<MinRequiredDataVersion>() )).Returns(true);
额外优化建议
你当前mockApiVersion的Setup返回的是无属性赋值的ApiVersion实例,后续如果ApplicationVersionDto构造时用到apiVersion的值可能会出现空引用问题,建议补充赋值:
fixture.mockApiVersion.SetupGet(o => o.Value).Returns(new ApiVersion(){ Version = "1.0.0" });
内容的提问来源于stack exchange,提问作者Shane Rich
相关产品推荐
相关产品推荐

