We have a controller that derives from ControllerBase
with an action like this:
public async Task Get(int id)
{
try
{
The null exception is because of a missing ProblemDetailsFactory
In this case the controller needs to be able to create ProblemDetails
instance via
[NonAction]
public virtual ObjectResult Problem(
string detail = null,
string instance = null,
int? statusCode = null,
string title = null,
string type = null)
{
var problemDetails = ProblemDetailsFactory.CreateProblemDetails(
HttpContext,
statusCode: statusCode ?? 500,
title: title,
type: type,
detail: detail,
instance: instance);
return new ObjectResult(problemDetails)
{
StatusCode = problemDetails.Status
};
}
Source
ProblemDetailsFactory
is a settable property
public ProblemDetailsFactory ProblemDetailsFactory
{
get
{
if (_problemDetailsFactory == null)
{
_problemDetailsFactory = HttpContext?.RequestServices?.GetRequiredService();
}
return _problemDetailsFactory;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_problemDetailsFactory = value;
}
}
Source
that could be mocked and populated when testing in isolation.
[TestMethod]
public async Task GetCallsProblemOnInvalidId() {
//Arrange
var problemDetails = new ProblemDetails() {
//...populate as needed
};
var mock = new Mock();
mock
.Setup(_ => _.CreateProblemDetails(
It.IsAny(),
It.IsAny(),
It.IsAny(),
It.IsAny(),
It.IsAny(),
It.IsAny())
)
.Returns(problemDetails)
.Verifyable();
var sut = new MyController(...);
sut.ProblemDetailsFactory = mock.Object;
//...
//Act
var result = await sut.Get(someInvalidId);
//Assert
mock.Verify();//verify setup(s) invoked as expected
//...other assertions
}