I am developing a Web API that in some cases will respond with 500 (ugly design, I know, but can't do anything about it). In tests there's an ApiFixture that contains AspNetCore.TestHost:
public class ApiFixture
{
public TestServer ApiServer { get; }
public HttpClient HttpClient { get; }
public ApiFixture()
{
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var path = Assembly.GetAssembly(typeof(ApiFixture)).Location;
var hostBuilder = new WebHostBuilder()
.UseContentRoot(Path.GetDirectoryName(path))
.UseConfiguration(config)
.UseStartup<Startup>();
ApiServer = new TestServer(hostBuilder);
HttpClient = ApiServer.CreateClient();
}
}
When I am calling API endpoint with HttpClient from this fixture it should respond with 500, instead I am getting exception that is being raised in the tested controller. I know that in tests it might be a nice feature, but I don't want that - I want to test actual behavior of controller, which is returning internal server error. Is there a way to reconfigure TestServer to return response?
Code in controller action is irrelevant, can be throw new Exception();
Use the UseExceptionHandler middleware in ASP.NET Core So, to implement the global exception handler, we can use the benefits of the ASP.NET Core build-in Middleware. A middleware is indicated as a software component inserted into the request processing pipeline which handles the requests and responses.
You can create an exception handling middleware and use it in tests or better always
public class ExceptionMiddleware
{
private readonly RequestDelegate next;
public ExceptionMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext httpContext)
{
try
{
await this.next(httpContext);
}
catch (Exception ex)
{
httpContext.Response.ContentType = MediaTypeNames.Text.Plain;
httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
await httpContext.Response.WriteAsync("Internal server error!");
}
}
}
Now you can register this middleware in your Startup.cs:
...
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMiddleware<ExceptionMiddleware>();
...
app.UseMvc();
}
And if you don't want to use it all the time you can create TestStartup
- a child class of your Startup
and override Configure
method to call UseMiddleware
only there. Then you will need to use the new TestStartup
class in the tests only.
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