0

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.

0

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.