我有一个ErrorHandlingMiddleware类,它跨多个项目使用,因此存在于一个共享库中(而不是在API中),我想为它编写一些测试。我已经使用TestServer编写了一个通过测试的代码(如this article中所述),这证明了当端点没有抛出异常时,我的中间件可以工作,但是我在研究如何故意引发异常以触发错误处理部分时遇到了麻烦。
我在这上面找到的唯一一件事是this question,它与我想要的正好相反。
这是我的中间件代码- ErrorHandlingService,它可以很好地处理和格式化我的所有错误。
public ErrorHandlingMiddleware(RequestDelegate next, IErrorHandlingService errHandler)
{
_next = next;
_errHandler = errHandler;
}
public async Task Invoke(HttpContext context, IHostEnvironment env)
{
try
{
_errHandler.AddRequestInformation(Guid.NewGuid(), DateTime.Now, $"{context.Request.Method} {context.Request.Path}");
await _next(context);
}
catch (Exception ex)
{
_errHandler.AddError(new MyError()
{
Title = "An unknown error occurred during execution",
ErrorID = "---",
ErrorMessage = env.IsProduction() ? "" : ex.ToString(),
HttpCode = HttpStatusCode.InternalServerError
});
context.Response.StatusCode = (int)_errHandler.ErrorResponse.StatusCode;
await context.Response.WriteAsJsonAsync(_errHandler.ErrorResponse);
}
}
以及测试是否抛出“无”异常的通过测试。
public class ErrorHandlingMiddlewareTests
{
private async Task<IHost> GetHost()
{
return await new HostBuilder()
.ConfigureWebHost(webBuilder =>
{
webBuilder
.UseTestServer()
.ConfigureServices(services =>
{
services.Add(ServiceDescriptor.Scoped<IErrorHandlingService, ErrorHandlingService>());
})
.Configure(app =>
{
app.UseMiddleware<ErrorHandlingMiddleware>();
});
})
.StartAsync();
}
[Fact]
public async Task NewRequest_AddsRequestInformation()
{
// Arrange
using var host = await GetHost();
var requestRoute = "/route/to/endpoint";
var server = host.GetTestServer();
server.BaseAddress = new Uri("https://example.com/");
// Act
var context = await server.SendAsync(c => //throws a 404, I'm not testing for that
{
c.Request.Method = HttpMethods.Get;
c.Request.Path = requestRoute;
});
// Assert
var errorResponse = host.Services.GetService<IErrorHandlingService>().ErrorResponse;
errorResponse.ErrorContent.Request.Should().Be("GET " + requestRoute);
errorResponse.ErrorContent.TraceID.Should().NotBeEmpty();
}
}
那么,现在如何让测试服务器抛出一个可以被中间件捕获的异常呢?
2条答案
按热度按时间qyzbxkaa1#
好吧,不到24小时后,我解决了这个问题,结果和往常一样,我只需要睡一觉就可以了。StripingWarrior的评论将我引向了一个guide,虽然没有说任何我不知道的事情,但确实促使我思考一个应用程序实际上是如何在.NET中构建的,以及一个普通的API将在哪里寻找控制器/路由。
长话短说,经过一些试验和错误,以及对Startup.cs如何工作的一些研究和一些routing basics,这里是我如何解决的:
使用一些新端点的内联定义意味着我可以轻松地控制进出的内容,并且如果需要的话,可能会使响应变得更加复杂。我想你很少使用本地TestServer在类库中测试东西,但我希望这对下一个没有Startup类的人有帮助。
a8jjtwal2#
一种方法是用一个标志重载处理程序,并将其 Package 在DEBUG中,这样它就不会出现在生产构建中。