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.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0