0

I'm trying to unit test a controller. SomeController inherits from BaseController. BaseController inherits from Microsoft.AspNetCore.Mvc.Controller.

My NUnit tests fail because a property Response in Controller is always null when running my tests. My test currently looks like this:

[Test]
public void GetByFilter_ShouldReturnABadRequest_WhenModelStateIsInvalid()
{
    _sut.ModelState.AddModelError("SessionName", "Required");
    var result = _sut.GetByFilter(_mockedFilter);
    Assert.IsAssignableFrom<BadRequestObjectResult>(result);
}

_sut is set by [SetUp] with this method:

protected override void InitSut() => _sut =
        new SomeController(_mockedLogger, _mockedService, _mockedRepository, _mockedHtmlSanitizer);

The code that fails on tests but works fine when running looks like this:

Response.Headers.Add("RowCount", result.Count().ToString());
return Ok(result);

Seems I need to do something to have the BaseController set the Response. In production the Response is filled with an instance of HttpDefaultResponse, but Response is readonly, so no way to set this myself.

I have tried following testing guides like this, but without luck:
https://learn.microsoft.com/en-us/aspnet/web-api/overview/testing-and-debugging/unit-testing-controllers-in-web-api

What do I need to do to start my controllers correctly and thus pass my tests?

1 Answers1

0

Rather than using the Response property, create a custom response via

var response = Request.CreateResponse(HttpStatusCode.Ok, result);

then you can add headers as needed

response.Headers.Add("RowCount", result.Count().ToString());

and return this as a result.

IActionResult rtn = ResponseMessage(response);
return rtn;

You may need to set or mock the Request object in your unit tests.

Kami
  • 19,134
  • 4
  • 51
  • 63
  • This would only replace my problem with Response to Request. Request is also readonly so mocking is not an option, thus leaving me with the same problem. – Stijn Wingens Oct 07 '21 at 07:30
  • 1
    Although this question has different answers pointed out in different places, I came across this solution (https://stackoverflow.com/a/55045637/5416602) by @Plank and that worked best for me. Giving real HttpContext to controller resolves Request and Response issue without changing the actual code. `_controller.ControllerContext.HttpContext = new DefaultHttpContext();` – Umair Malhi Jan 02 '23 at 12:41