You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单元测试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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:32:49