我已经为Web API编写了一个 Action 过滤器。如果api Controller 中的方法抛出未处理的异常,则过滤器将创建内部错误500响应。
我需要知道如何测试过滤器?
我已经进行了广泛的研究,但无法创建合适的测试。我尝试了上下文模拟,服务定位器实现,甚至使用测试服务器进行集成测试。
Web API Controller 如下所示:
namespace Plod.Api.ApiControllers
{
[TypeFilter(typeof(UnhandledErrorFilterAttribute))]
[Route("api/[controller]")]
public class GamesController : BaseApiController
{
public GamesController(IGameService repository,
ILogger<GamesController> logger,
IGameFactory gameFactory
) : base(
repository,
logger,
gameFactory
)
{ }
// ..... controller methods are here
}
}
完整的 Controller 位于here。
过滤器是这样的:
namespace Plod.Api.Filters
{
public class UnhandledErrorFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Exception != null)
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.ExceptionHandled = true;
}
}
}
}
我什至欢迎对过滤器实现进行更改,以解决此问题。任何帮助或想法将不胜感激。谢谢。
最佳答案
你可能做不到。但是,您可以做的是旋转 TestServer
,然后使用HttpClient对其进行设置。这确实是集成测试,而不是单元测试。但是,这是一种很好的集成测试,因为它可以在管道中安全运行。
本文档说明了如何执行此操作:
https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-3.1
您将要面对的问题是,您将需要在应用程序内部模拟基础服务。如果不这样做,整个服务器将启动,并尝试访问数据库等。这是一个示例。这是使用最小起订量。顺便说一句,我与单元测试共享ConfigureServices
方法,因此它们使用相同的模拟服务对象网格。您仍然可以使用Moq或NSubstitute的全部功能来测试后端(甚至前端)。
我可以在测试中使用断点击中我的属性。
private void ConfigureServices(IServiceCollection services)
{
var hostBuilder = new WebHostBuilder();
hostBuilder.UseStartup<TestStartup>();
hostBuilder.ConfigureServices(services =>
{
ConfigureServices(services);
});
_testServer = new TestServer(hostBuilder);
_httpClient = _testServer.CreateClient();
}
private void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(_storageManagerFactory.Object);
services.AddSingleton(_blobReferenceManagerMock.Object);
services.AddSingleton(_ipActivitiesLoggerMocker.Object);
services.AddSingleton(_loggerFactoryMock.Object);
services.AddSingleton(_hashingService);
services.AddSingleton(_settingsServiceMock.Object);
services.AddSingleton(_ipActivitiesManager.Object);
services.AddSingleton(_restClientMock.Object);
_serviceProvider = services.BuildServiceProvider();
}
public class TestStartup
{
public void Configure(
IApplicationBuilder app,
ISettingsService settingsService)
{
app.Configure(settingsService.GetSettings());
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
var mvc = services.AddMvc(option => option.EnableEndpointRouting = false);
mvc.AddApplicationPart(typeof(BlobController).Assembly);
services.AddSingleton(new Mock<IHttpContextAccessor>().Object);
return services.BuildServiceProvider();
}
}
关于asp.net-core-mvc - 如何在asp.net核心中对Web api的 Action 过滤器属性进行单元测试?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46576517/