I am writing unit test for controllers and was running into an issue where it seems the Mocked object is not getting setup when I inject it. If however I create the Mocked object in the controller end point everything works fine. Finally to further complicate things I am doing my unit testing via a fluent builder pattern.
First here is a working snip:
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
}
Now as a heads up this gets a little more involved.
First I have my controller being created by a builder:
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);
}
}
Now my unit test uses the builder:
[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);
}
Finally in the controller
var crt = _xRepository.Object.GetDat(datId, ref errorInfo);
//crt is null????
Any pointers where I'm getting off track would be greatly appreciated.
This issue is being caused by your
GetDat
method taking a ref parameter. Essentially, unless you're passing the same instance to the call that you're passing to theSetup
, it will fail to match the Setup. More details can be found here, along with a suggested workaround using RhinoMocks. I think it'd probably also work with NSubstitute, but I haven't tested that.Looking at what you're doing though, do you really need errorInfo to be passed by ref? It's an instance of a list class, which presumably your repository might add to. Is it really going to need to reassign the errorInfo to a different instance of the class? If not, then you could change the signature to a non-ref one and then set up your mock as follows (either should work):
Or