Reputation: 85
I want to test Web api 2 post method, which looks like this:
[HttpPost]
[ValidateAntiForgeryToken]
public IHttpActionResult CreateEquipment(EquipmentDto equipmentDto)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
var equipment = Mapper.Map<EquipmentDto, Equipment>(equipmentDto);
unitOfWork.Equipment.Add(equipment);
unitOfWork.Complete();
equipmentDto.Id = equipment.Id;
return Created(new Uri(Request.RequestUri + "/" + equipment.Id), equipmentDto);
}
I am using Moq and NUnit to test. My SetUp method and test method look like this:
[SetUp]
public void SetUp()
{
unitOfWork = new Mock<IUnitOfWork>();
controller = new EquipmentController(unitOfWork.Object);
Mapper.Initialize(c => c.AddProfile<MappingProfile>());
}
[Test]
public void CreateEquipment_ModelIsValid_ReturnCreated()
{
var equipmentDto = new EquipmentDto();
var equipment = Mapper.Map<EquipmentDto, Equipment>(equipmentDto);
unitOfWork.Setup(uow => uow.Equipment.Add(equipment));
unitOfWork.Setup(uow => uow.Complete());
var result = controller.CreateEquipment(equipmentDto) as CreatedAtRouteNegotiatedContentResult<EquipmentDto>;
Assert.IsNotNull(result);
}
I am getting NullReferenceException in the controller's line:
return Created(new Uri(Request.RequestUri + "/" + equipment.Id), equipmentDto);
equipment.Id and equipmentDto are not null. The null is Request, that's why Request.RequestUri throws an exception.
How to set up the Request properly to avoid the exception and pass the test? I would appreciate any help.
I know there is a similiar question: ASP.NET Testing Api controller: Uri(Request.GetEncodedUrl()...) returns null But that is related to ASP.NET Core and I coulnd't find out how to resolve the problem in ASP.NET MVC.
EDIT: Also tried to add this in the test method:
var context = new Mock<HttpContextBase>();
context.Setup(x => x.Request.Url).Returns(new Uri("/Equipment/New", UriKind.Relative));
But it didn't help.
Upvotes: 0
Views: 770
Reputation: 895
You need to configure your controller with HttpRequestMessage
like:
var request = new HttpRequestMessage()
{
RequestUri = new Uri("http://localhost:5000/Equipment/New", UriKind.Absolute)
};
var controllerContext = new HttpControllerContext
{
Request = request
};
var controller = new EquipmentController(unitOfWork.Object)
{
ControllerContext = controllerContext
};
...
var result = controller.CreateEquipment(equipmentDto) as CreatedNegotiatedContentResult<EquipmentDto>;
Assert.NotNull(result);
Also note that you return CreatedNegotiatedContentResult
from the endpoint but not CreatedAtRouteNegotiatedContentResult
Upvotes: 2