我正在为控制器编写单元测试,并且遇到了一个问题,当我注入时,Mocked对象似乎没有得到设置。但是,如果我在控制器端点创建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????
我非常感谢任何我偏离轨道的指示。
答案 0 :(得分:1)
此问题是由GetDat
方法获取ref参数引起的。基本上,除非您将同一个实例传递给您传递给Setup
的呼叫,否则它将无法与安装程序匹配。可以找到更多详细信息here,以及使用RhinoMocks的建议解决方法。我认为它可能也适用于NSubstitute,但我还没有测试过。
看看你正在做什么,你真的需要通过ref传递errorInfo吗?它是列表类的一个实例,可能是您的存储库可能添加的。是否真的需要将errorInfo重新分配给该类的其他实例?如果没有,那么您可以将签名更改为非参考签名,然后按如下方式设置您的模拟(要么应该工作):
_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());