使用Moq测试无返回值Task方法时遇空引用异常问题
Moq设置Task返回值触发空引用异常的排查与解决
问题场景
我有这么一个方法定义:
Task SendMessage(ServiceBusRequest serviceBusRequest);
在单元测试里做了两种Mock设置,都抛出空引用异常:
第一种设置:
_serviceBusAdapter.Setup(p => p.SendMessage(It.IsAny<ServiceBusRequest>())).Returns(Task.FromResult(default(object)));
第二种尝试:
_serviceBusAdapter.Setup(p => p.SendMessage(It.IsAny<ServiceBusRequest>())).Returns(Task.CompletedTask);
使用的Moq版本是4.16.0。
常见原因及解决办法
Mock实例未初始化
这是最大概率的问题:如果_serviceBusAdapter是Mock对象,但你没先通过new Mock<你的接口类型>()创建实例,直接调用Setup肯定会空引用。
解决:先实例化Mock对象再做Setup:// 先创建Mock实例,替换成你的实际接口名 var _serviceBusAdapter = new Mock<IServiceBusAdapter>(); _serviceBusAdapter.Setup(p => p.SendMessage(It.IsAny<ServiceBusRequest>())).Returns(Task.CompletedTask);接口方法是显式实现
如果SendMessage是接口的显式实现,Moq默认可能匹配不到,需要调整Setup的写法,明确指定接口类型:_serviceBusAdapter.Setup(p => ((IServiceBusAdapter)p).SendMessage(It.IsAny<ServiceBusRequest>())).Returns(Task.CompletedTask);ServiceBusRequest类型的匹配问题
极少数情况,如果ServiceBusRequest是值类型,或者你的测试代码里对传入的参数有非空校验,但Moq的匹配逻辑出现异常,可尝试更具体的匹配方式,比如:_serviceBusAdapter.Setup(p => p.SendMessage(It.Is<ServiceBusRequest>(req => req != null))).Returns(Task.CompletedTask);
总结
优先检查Mock对象是否已正确实例化,这是引发这类空引用异常最常见的原因,确认后再根据实际场景调整Setup写法。
内容的提问来源于stack exchange,提问作者MAK
相关产品推荐
相关产品推荐

