最小起订量对象设置范围/上下文因构建器模式单元测试和 Web API 控制器而丢失

本文关键字:单元测试 模式 Web API 控制器 构建 对象 设置 上下文 范围 | 更新日期: 2023-09-27 17:57:07

我正在为控制器编写单元测试,并且遇到了一个问题,即当我注入 Mocked 对象时似乎没有设置它。但是,如果我在控制器端点中创建模拟对象,则一切正常。最后,为了使事情进一步复杂化,我正在通过流畅的构建器模式进行单元测试。

首先是一个工作截图:

public HttpResponseMessage AddSlot(AddSlotRequest requestList)
{
   var errorInfo = new List<ErrorInfo>();
   Mock<IdatRepository> _xRepository = new Mock<IdatRepository>();
   _xRepository.Setup(x => x.GetDat(It.IsAny<Guid>(), ref errorInfo))
     .Returns(new Dat());
 ....snip....
 var crt = _xRepository.Object.GetDat(datId, ref errorInfo);
  //crt object returned as expected from mock
 ....snip
}

现在作为提醒,这变得更加复杂。

首先,我的控制器由构建器创建:

public class AddSlotControllerBuilder
{
    //private backing field for fluent methods to act upon
    private Mock<IdatRepository> _xRepository = new Mock<IdatRepository>();
    //exposed property for external interactions...
    //not doing any yet but had plans so that is why it is here
    public Mock<IdatRepository> MoqdatRepository { get; private set; }
    //following the builder pattern the build method is called to return 
    //the object after configuration complete
    public AddSlotController Build()
    {
       var errorInfo = new List<ErrorInfo>();
       _xRepository.Setup(x => x.GetDat(It.IsAny<Guid>(), ref errorInfo)).Returns(new Dat());

        //assign private mock field to property
        MoqdatRepository = _xRepository;
        return new AddSlotController(_xRepository.Object);
    }
}

现在我的单元测试使用构建器:

[TestMethod]
public void AddValidPickupSlotCorrectResponse()
{
   var errorInfo = new List<ErrorInfo>(); //ref field 
   //arrange
   //1. controller
   AddSlotController controller = new AddSlotControllerBuilder().Build();
  //skipping APSR for brevity
   //act
   controller.AddPickupSlot(APSR);
}

最后在控制器中

  var crt = _xRepository.Object.GetDat(datId, ref errorInfo);
  //crt is null????

任何我偏离轨道的指示将不胜感激。

最小起订量对象设置范围/上下文因构建器模式单元测试和 Web API 控制器而丢失

此问题

是由采用 ref 参数的GetDat方法引起的。 从本质上讲,除非您将同一实例传递给要传递给Setup的调用,否则它将无法匹配安装程序。 可以在此处找到更多详细信息,以及使用RhinoMocks的建议解决方法。 我认为它也可能与NSubstitute一起使用,但我还没有测试过。

看看你在做什么,你真的需要错误信息通过引用传递吗? 它是列表类的一个实例,大概您的存储库可能会添加到该实例中。 是否真的需要将错误信息重新分配给类的不同实例? 如果没有,那么您可以将签名更改为非 ref 签名,然后按如下方式设置您的模拟(两者都应该有效):

_xRepository.Setup(x => x.GetDat(It.IsAny<Guid>(), It.IsAny<List<ErrorInfo>>()))
                         .Returns(new Dat());

_xRepository.Setup(x => x.GetDat(It.IsAny<Guid>(), errorInfo))
                         .Returns(new Dat());