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
GetDatmethod 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