如何Mock带ref参数的无返回值接口方法?报错求解决
解决Moq中Ref参数方法的Callback参数不匹配问题
你遇到的错误核心原因很明确:Moq要求回调(Callback)的参数签名必须和被Mock方法的签名完全一致——包括ref修饰符。你的原方法两个参数都是ref类型,但Callback里用的是普通值参数,Moq无法匹配签名,因此抛出了ArgumentException。
解决方案:让Callback使用带ref修饰符的参数
只需要修改Callback的lambda表达式,给参数加上ref修饰符,和原方法的参数签名对齐即可。
完整的正确代码示例:
var repoMock = new Mock<ILedgerStoreRepository>(); // Setup保持原有的ref参数匹配逻辑,Callback添加ref修饰符对齐签名 repoMock.Setup(m => m.AddInvoiceDetailsToBatchWriteObj(ref batchWriteObj1, ref It.Ref<InvoiceDetailsDAO>.IsAny)) .Callback((ref BatchWrite<InvoiceDetailsDAO> write, ref InvoiceDetailsDAO dao) => { // 正常验证invoiceDetails的值 Assert.Equal(LedgerStoreTestConstants.TestInvoiceDetailsMappingDao, dao); }) .Verifiable(); // 执行被测试代码,触发对AddInvoiceDetailsToBatchWriteObj的调用 // 最后验证方法确实被调用过 repoMock.Verify();
额外优化:忽略不需要的Ref参数
如果你不需要操作或验证第一个ref BatchWrite<InvoiceDetailsDAO>参数,可以用下划线_代替参数名,让代码更简洁:
repoMock.Setup(m => m.AddInvoiceDetailsToBatchWriteObj(ref batchWriteObj1, ref It.Ref<InvoiceDetailsDAO>.IsAny)) .Callback((ref BatchWrite<InvoiceDetailsDAO> _, ref InvoiceDetailsDAO dao) => { Assert.Equal(LedgerStoreTestConstants.TestInvoiceDetailsMappingDao, dao); }) .Verifiable();
关键知识点回顾
Moq在处理带有ref/out修饰符的方法时,会严格校验回调委托的参数签名是否与原方法一致。只要回调的参数没有对应ref修饰符,Moq就会判定签名不匹配,抛出参数无效的异常。确保回调参数和原方法完全一致,就能快速解决这个问题。
内容的提问来源于stack exchange,提问作者BMD
相关产品推荐
相关产品推荐

