Moq Verify验证泛型方法调用失效,如何排查解决?
问题原因及解决方案
你的测试失败核心原因是泛型方法的类型参数匹配不兼容:
在Repository.Save方法中,遍历e.GetEvents()得到的ev编译时类型是Event(因为GetEvents()返回IList<Event>),所以实际调用的是PublishEvent<Event>(Event ev);但你在Mock中配置和验证的是PublishEvent<EventToVerify>(EventToVerify ev)——Moq会严格区分不同泛型参数的方法实例,因此认为没有匹配的调用记录。
解决方法(二选一即可)
方法1:修改Repository代码,让泛型参数按实际类型推断
将Save方法中的调用改为使用dynamic,让运行时根据事件的实际类型推断泛型参数:
public void Save(Entity e) { // persistence logic here foreach (var ev in e.GetEvents()) { _publisher.PublishEvent((dynamic)ev); } }
这样调用时会根据ev的实际类型(比如EventToVerify)自动匹配对应的泛型方法实例,你的原有Mock验证代码就能正常工作。
方法2:修改Mock验证逻辑,匹配正确的泛型参数
如果不想改动业务代码,可以调整验证逻辑,匹配泛型参数为Event且实际类型是EventToVerify的调用:
// 替换原有Verify代码 mockBus.Verify(e => e.PublishEvent(It.Is<Event>(ev => ev is EventToVerify)), Times.AtLeastOnce);
或者更宽松地匹配所有Event类型的泛型调用(如果不需要限定具体子类型):
mockBus.Verify(e => e.PublishEvent(It.IsAny<Event>()), Times.AtLeastOnce);
另外建议:优先针对IEventPublisher接口创建Mock,而非MessageBus类,更符合依赖注入的设计原则:
var mockBus = new Mock<IEventPublisher>();
内容的提问来源于stack exchange,提问作者AMG
相关产品推荐
相关产品推荐

