单元测试Mock返回Null问题求助:Moq与NSubstitute均失效
问题排查与解决
核心问题原因
- Moq匹配失败:你在测试中提前反序列化得到
input对象,并用它来设置Mock的匹配条件,但函数func1内部会重新对传入的JSON字符串做反序列化,得到的是另一个全新的List<Order>实例。Moq默认按对象引用相等判断参数是否匹配,两个不同实例无法匹配,因此返回默认值null。 - NSubstitute参数类型错误:你给
myOrder方法传入了字符串类型的ValidJson1,但接口定义的myOrder参数是List<Order>,参数类型完全不匹配,自然不会触发预期的返回值。
修正方案
1. 修复Moq的Mock设置
改用参数匹配器,要么匹配任意List<Order>,要么按属性值精准匹配:
- 匹配任意
List<Order>(适合不关心参数具体内容的场景):
myInterfaceMock.Setup(m => m.myOrder(It.IsAny<List<Order>>())).Returns(ValidOutputJson1);
- 按属性值精准匹配(适合需要验证参数内容的场景):
myInterfaceMock.Setup(m => m.myOrder(It.Is<List<Order>>(orders => orders.Count == 1 && orders[0].OrderNo == "Pizz111" && orders[0].CreatedBy == "test@test.org"))) .Returns(ValidOutputJson1);
2. 修复NSubstitute的Mock设置
必须传入List<Order>类型的参数,而非字符串:
var input = JsonConvert.DeserializeObject<List<Order>>(ValidJson1); // 匹配指定对象或用匹配器匹配任意实例 myInterfaceSubsititueMock.myOrder(input).Returns(ValidOutputJson1); // 或 myInterfaceSubsititueMock.myOrder(Arg.Any<List<Order>>()).Returns(ValidOutputJson1);
完整修正后的测试代码
public void shouldReturnOkObjectResultifInputisValid() { // 注意:移除了原JSON中多余的逗号,避免反序列化失败 string ValidJson1 = @"[ { ""CreatedBy"":""test@test.org"", ""OrderNo"":""Pizz111"", ""Amount"":""10$"" } ]"; string ValidOutputJson1 = @"{""OrderNo"": ""808098"",""Item"": ""Pizza""}"; Mock<IMyInterface> myInterfaceMock = new Mock<IMyInterface>(); // 使用任意参数匹配器 myInterfaceMock.Setup(m => m.myOrder(It.IsAny<List<Order>>())).Returns(ValidOutputJson1); funcMyFunctionApp funcRequest = new funcMyFunctionApp(myInterfaceMock.Object); // Act var result = funcRequest.func1(ValidJson1); // Assert Assert.Multiple(() => { Assert.That(((OkObjectResult)result).Value as string, Is.EqualTo(ValidOutputJson1)); }); }
内容的提问来源于stack exchange,提问作者Abhinav Singh
相关产品推荐
相关产品推荐

