ASP.NET Core中Mock测试验证时触发IsCollectible调用异常求助
Moq Verify含Out参数时触发异常的解决方案
问题分析
你遇到的异常「评估方法System.Linq.Expressions.Expression.Call时需要调用System.RuntimeType.get_IsCollectible方法,该方法无法在此上下文调用」,是因为Moq在解析包含out参数的验证表达式时,对变量引用的处理触发了环境不支持的类型属性访问。
修复方案
方案1:使用Moq内置的out参数匹配器
将Setup和Verify中的out变量替换为It.Ref<T>.IsAny,让Moq忽略具体的out变量值,只验证方法调用次数:
private Mock<Icache<string>> _mockobj; [TestInitialize] public void Initialize() { _mockobj = new Mock<Icache<string>>(); } [TestMethod] public async Task methodName() { // 配置mock的out参数匹配 _mockobj.Setup(x => x.get("keyname", out It.Ref<string>.IsAny)).Returns(true); // 【关键】这里需要调用依赖该mock的业务方法,触发mock的get方法执行 // 示例:var targetService = new YourBusinessService(_mockobj.Object); // await targetService.ExecuteMethodThatUsesCache(); // 验证方法调用次数 _mockobj.Verify(x => x.get("keyname", out It.Ref<string>.IsAny), Times.Once()); }
方案2:验证out参数的具体值
如果需要验证out参数的输出值,可以提前声明变量并复用:
private Mock<Icache<string>> _mockobj; private string expectedId; [TestInitialize] public void Initialize() { _mockobj = new Mock<Icache<string>>(); expectedId = "target-id-value"; // 设置预期的out参数值 } [TestMethod] public async Task methodName() { // 配置mock返回指定的out参数值 _mockobj.Setup(x => x.get("keyname", out expectedId)).Returns(true); // 调用业务方法触发mock调用 // var targetService = new YourBusinessService(_mockobj.Object); // await targetService.ExecuteMethodThatUsesCache(); // 验证方法调用次数及out参数值 _mockobj.Verify(x => x.get("keyname", out expectedId), Times.Once()); }
额外注意事项
- 必须在Verify之前实际调用依赖mock的业务方法,否则Verify会因为方法从未被调用而失败。
- 确保你的Moq版本是最新的,旧版本可能存在out参数表达式解析的兼容性问题。
内容的提问来源于stack exchange,提问作者Krishna Soni
相关产品推荐
相关产品推荐

