FakeItEasy返回Null异常:Xunit测试中对象判空逻辑失效排查
问题原因与解决方案
核心原因
FakeItEasy 默认会为非可空引用类型自动生成假实例,而非返回 null。另外如果测试中参数匹配不精确、返回值未正确包装为异步任务,也会导致设置的 null 返回规则不生效。
具体排查与解决步骤
1. 检查仓库方法的返回类型
首先确认 IProductionOrderRepository.CreateProductionOrder 的返回类型是否为可空引用类型:
- 如果是
Task<ProductionOrderDto>(非可空),FakeItEasy 会自动生成假的ProductionOrderDto实例,忽略你的 null 设置(符合 C# 可空引用类型的约束)。 - 正确的做法是将返回类型改为
Task<ProductionOrderDto?>(可空):
public interface IProductionOrderRepository { Task<ProductionOrderDto?> CreateProductionOrder(Product product, ProductionOrder order); }
2. 正确设置 FakeItEasy 返回 null
针对异步方法,需要将 null 包装为对应的 Task:
A.CallTo(() => fakePORepository.CreateProductionOrder(allProducts[0], invalidProductionOrder)) .Returns(Task.FromResult<ProductionOrderDto?>(null));
如果你的 C# 版本支持目标类型推断,也可以简化为:
A.CallTo(() => fakePORepository.CreateProductionOrder(allProducts[0], invalidProductionOrder)) .Returns((ProductionOrderDto?)null);
3. 验证参数匹配是否精确
如果测试中传入的 invalidProductionOrder 和业务代码调用时的实例不匹配,FakeItEasy 会执行默认行为(返回假实例)。可以用忽略参数的方式验证:
A.CallTo(() => fakePORepository.CreateProductionOrder(allProducts[0], A<ProductionOrder>.Ignored)) .Returns(Task.FromResult<ProductionOrderDto?>(null));
4. 无法修改返回类型的兼容方案
如果因项目限制无法修改仓库方法的返回类型,可使用 ReturnsNull() 或强制返回 null:
// 方式1:使用FakeItEasy的ReturnsNull方法 A.CallTo(() => fakePORepository.CreateProductionOrder(allProducts[0], invalidProductionOrder)) .ReturnsNull(); // 方式2:用null!抑制可空警告 A.CallTo(() => fakePORepository.CreateProductionOrder(allProducts[0], invalidProductionOrder)) .Returns(Task.FromResult<ProductionOrderDto>(null!));
内容的提问来源于stack exchange,提问作者StarGazer.
相关产品推荐
相关产品推荐

