I have written this controller method and this test.
Controller method:
public async Task<IActionResult> Metric(string type, string source)
{
// Check existence ...
var model = await _context
.Metrics
.FirstAsync(mt => mt.Type == metricType.AsInt() && mt.Source == source);
Response.StatusCode = HttpStatusCode.OK.AsInt();
return View(model);
}
Test:
[Fact]
public async Task MetricExistsTest()
{
// Arrange ...
// Act
var result = await _controller.Metric(Metrics.CpuLoad.ToString(), "source-1");
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Equal(HttpStatusCode.OK.AsInt(), viewResult.StatusCode.Value);
var model = Assert.IsAssignableFrom<Metric>(
viewResult.ViewData.Model
);
}
Now, the problem is here Assert.Equal(HttpStatusCode.OK.AsInt(), viewResult.StatusCode.Value);. The viewResult.StatusCode is indeed null. If I comment that line out, everything works.
What am I doing wrong? Why is it null? Do I properly set Response.StatusCode? How do I verify status code then?
Thank you!
I finally did it! All those who helped me with answers and comments - I very much appreciate it!
It turns out that I had two problems - HttpContext does not exist (unless set manually) in testing environment and Response.StatusCode does not set StatusCode on resulting ViewResult object. (These are my observations, correct me if I'm wrong).
Problem 1 solution:
As simple as setting default HttpContext solves the problem. At least, controller method does not crash because Response is not null anymore.
var controller = new HomeController();
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
Problem 2 solution:
It turns out that I need to set StatusCode explicitly on ViewResult object. For some reason, ASP.Core does not mirror StatusCode from Response object to resulting IActionObject. (Correct me if I'm wrong)
So here is the solution (it's another method on my controller, but it clearly demonstrates the idea):
public async Task<IActionResult> Index()
{
var model = await _context
.Metrics
.Where(mt => mt.Type == Metrics.CpuLoad.AsInt())
.ToListAsync();
var result = View(model);
result.StatusCode = (model.Any() ? HttpStatusCode.OK : HttpStatusCode.NoContent).AsInt();
return result;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With