使用Moq Mock含struct类型入参的方法时报NotSupported错误如何解决
问题根本原因
报错和TimeSpan是struct类型无关,核心是Moq只能拦截虚方法、抽象方法、接口定义的方法,你要Mock的S2SJwtGenerator.Generate是普通非虚实例方法,Moq无法重写该方法的实现,因此无论怎么调整参数匹配规则都会抛出NotSupported异常。
解决方法
方案1:Mock对应接口(优先推荐)
该类已经实现了IS2SJwtGenerator接口,按照单元测试最佳实践,直接依赖接口而非具体实现做Mock即可,代码调整如下:
// 将Mock的泛型参数从具体类改为对应的接口 protected readonly Mock<IS2SJwtGenerator> tokenGen = new Mock<IS2SJwtGenerator>(); var ts = new TimeSpan(1,1,1); // 直接正常配置即可,不需要特殊处理值类型参数 tokenGen.Setup(x => x.Generate(_testTenantId, null, ts)).Returns("NEWTOKEN");
方案2:将目标方法标记为虚方法
如果确实需要Mock具体类的实现,只需给原类的Generate方法加上virtual修饰符:
public class S2SJwtGenerator : BaseJwtGenerator, IS2SJwtGenerator { public S2SJwtGenerator(); // 添加virtual关键字 public virtual string Generate(string tenantId, string username, TimeSpan lifetime); }
修改后你原本的Setup代码就可以正常运行。
补充说明:
It.Ref<TimeSpan>.IsAny是用来匹配ref/out修饰的引用传递参数的,你的lifetime参数是值传递的struct,完全不需要使用该语法,之前的调整方向偏离了问题本质。
内容的提问来源于stack exchange,提问作者user3897533
相关产品推荐
相关产品推荐

