Mock IMyDate接口时触发NSubstitute UnexpectedArgumentMatcherException错误求助
解决NSubstitute的UnexpectedArgumentMatcherException错误
这个错误我之前也踩过坑!本质是你把NSubstitute的参数匹配器用错地方了——Arg.Is/Arg.Any这类工具只能用来匹配方法调用时传入的参数,绝对不能放到Returns()里面指定返回值。
先看你可能写错的错误代码:
var myDate = Substitute.For<IMyDate>(); // 这里犯了核心错误:把Arg.Any放到了Returns()里 myDate.GetDate().Returns(Arg.Any<DateTime>());
NSubstitute的参数匹配器是用来告诉框架“当调用某个方法时,如果传入的参数符合这个匹配规则,就返回指定值”,而不是用来生成返回值的。
正确的写法分几种场景:
1. 返回固定的DateTime值
如果只需要模拟返回一个固定日期,直接把具体值传给Returns()即可:
var myDate = Substitute.For<IMyDate>(); // 定义你想要模拟的固定日期 var mockDate = new DateTime(2024, 5, 20); myDate.GetDate().Returns(mockDate);
2. 返回动态生成的值
如果需要每次调用GetDate()时返回不同的动态值(比如模拟当前时间偏移),可以用接受委托的Returns()重载:
var myDate = Substitute.For<IMyDate>(); // 比如每次调用返回明天的当前时间 myDate.GetDate().Returns(() => DateTime.Now.AddDays(1));
3. 补充:带参数方法的正确匹配方式(避免混淆)
虽然你的GetDate()没有参数,但顺便提一下带参数方法的正确用法,加深理解:
假设接口有方法DateTime GetDate(int dayOffset),正确使用匹配器的方式是把匹配器放在方法的参数位置:
var myDate = Substitute.For<IMyDate>(); // 当传入任意int参数时,返回固定日期 myDate.GetDate(Arg.Any<int>()).Returns(new DateTime(2024, 6, 1)); // 当传入大于0的参数时,返回另一个日期 myDate.GetDate(Arg.Is<int>(x => x > 0)).Returns(new DateTime(2024, 7, 1));
核心总结:
Arg.Is/Arg.Any这类匹配器仅能出现在Mock方法的参数列表中,用于匹配调用时传入的参数。Returns()方法需要的是具体的返回值,或是能生成返回值的委托,绝对不能放参数匹配器。
内容的提问来源于stack exchange,提问作者user9530048
相关产品推荐
相关产品推荐

