使用NSubstitute配置链式方法返回值时遇Null问题求助
问题原因与解决方案
核心问题
你的mock配置未生效,导致Method1始终返回null,根源是参数匹配失败:测试代码配置mock时用了new List<Item>(),被测试方法调用时也创建了新的List<Item>实例,两个实例引用不同,NSubstitute默认严格匹配参数引用,因此配置的mock规则不会触发,返回默认的null。
具体解决办法
1. 使用NSubstitute参数匹配器(推荐)
用匹配器代替具体实例,让mock忽略列表的引用差异,只匹配类型或条件:
成功场景配置
_mockUserService.Method1(user, Arg.Any<List<Item>>(), true) .Returns(Task.FromResult(new Variable()));
异常场景配置
_mockUserService.Method1(user, Arg.Any<List<Item>>(), true) .Returns(Task.FromException<Variable>(new Exception()));
如果需要更精确的匹配(比如列表为空),可以用条件匹配:
_mockUserService.Method1(user, Arg.Is<List<Item>>(list => list != null && list.Count == 0), true) .Returns(...);
2. 检查Mock对象的创建合法性
如果UserService是具体类,NSubstitute只能mock它的虚方法/抽象方法:
- 若
Method1是非虚方法,NSubstitute无法拦截,会执行原方法逻辑,导致返回值不符合预期。 - 这种情况下,建议改为mock
UserService对应的接口(比如IUserService):
// 修改初始化代码 _mockUserService = Substitute.For<IUserService>(); _mockServiceFactory.GetUserService().Returns(_mockUserService);
3. 复用列表实例(局限性大)
如果必须匹配具体实例,需在测试代码和被测试方法中复用同一个列表对象:
// 测试Arrange阶段创建实例 var testItems = new List<Item>(); _mockUserService.Method1(user, testItems, true) .Returns(Task.FromResult(new Variable())); // 确保被测试方法调用Method1时使用同一个testItems实例
注:此方法仅适用于被测试代码允许外部传入列表的场景,通用性差。
验证步骤
- 替换参数匹配方式后重新运行测试,检查
await后的返回值是否符合配置。 - 若为具体类mock问题,改为对应接口mock,确保
Method1是接口定义的方法。
内容的提问来源于stack exchange,提问作者jmath412
相关产品推荐
相关产品推荐

