将 TestServer 用于错误场景
Using TestServer for error scenarios
我正在尝试使用 TestServer
来验证我的应用程序在出现异常时的行为方式。例如,在此示例中,我有一个控制器将调用数据库,但在我的测试中,我故意设置 repository
以引发异常。
[Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly IRepository _repo;
public ValuesController(IRepository repo)
{
_repo = repo;
}
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
this._repo.Execute();
return new string[] { "value1", "value2" };
}
}
我期待返回一个内部服务器错误。尽管如果是 F5 和 运行 我希望通过 TestServer
.
执行此操作的应用程序,这是可行的
[Fact]
public void Test1()
{
using (var client = new TestServer(new WebHostBuilder()
.UseStartup<TestStartup>())
.CreateClient())
{
var result = client.GetAsync("api/values").Result;
Assert.Equal(result.StatusCode, HttpStatusCode.InternalServerError);
}
}
public class TestStartup : Startup
{
protected override void ConfigureDependencies(IServiceCollection services)
{
services.AddSingleton<IRepository, FailingRepo>();
}
}
}
public class FailingRepo : IRepository
{
public void Execute()
{
throw new NotImplementedException();
}
}
相反,我得到的是测试失败:
System.AggregateException : One or more errors occurred. (The method
or operation is not implemented.)
如果我在管道的开头插入一些自定义中间件,我可以让它工作,类似于这样:
public class ErrorMiddleware
{
private RequestDelegate next;
private readonly ILogger logger;
public ErrorMiddleware(RequestDelegate next, ILogger logger)
{
this.next = next;
this.logger = logger;
}
public async Task Invoke(HttpContext context)
{
try
{
await this.next.Invoke(context);
}
catch (Exception e)
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
}
}
}
我记得能够通过完整的 .NET 框架中提供的 Owin 测试服务器来执行此操作。有什么想法如何去做吗?
您可以使用 WebApplicationFactory:
public class BasicTests
: IClassFixture<WebApplicationFactory<RazorPagesProject.Startup>>
{
private readonly WebApplicationFactory<RazorPagesProject.Startup> _factory;
public BasicTests(WebApplicationFactory<RazorPagesProject.Startup> factory)
{
_factory = factory;
}
而不是通用类型 RazorPagesProject.Startup
使用您自己的项目进行测试。工厂将为您提供访问所需路线的选项,并测试它们是否按您的要求执行:
// Arrange
var client = _factory.CreateClient();
// Act
var response = await client.GetAsync("api/Values");
//
response.EnsureSuccessStatusCode(); // Status Code 200-299
我正在尝试使用 TestServer
来验证我的应用程序在出现异常时的行为方式。例如,在此示例中,我有一个控制器将调用数据库,但在我的测试中,我故意设置 repository
以引发异常。
[Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly IRepository _repo;
public ValuesController(IRepository repo)
{
_repo = repo;
}
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
this._repo.Execute();
return new string[] { "value1", "value2" };
}
}
我期待返回一个内部服务器错误。尽管如果是 F5 和 运行 我希望通过 TestServer
.
[Fact]
public void Test1()
{
using (var client = new TestServer(new WebHostBuilder()
.UseStartup<TestStartup>())
.CreateClient())
{
var result = client.GetAsync("api/values").Result;
Assert.Equal(result.StatusCode, HttpStatusCode.InternalServerError);
}
}
public class TestStartup : Startup
{
protected override void ConfigureDependencies(IServiceCollection services)
{
services.AddSingleton<IRepository, FailingRepo>();
}
}
}
public class FailingRepo : IRepository
{
public void Execute()
{
throw new NotImplementedException();
}
}
相反,我得到的是测试失败:
System.AggregateException : One or more errors occurred. (The method or operation is not implemented.)
如果我在管道的开头插入一些自定义中间件,我可以让它工作,类似于这样:
public class ErrorMiddleware
{
private RequestDelegate next;
private readonly ILogger logger;
public ErrorMiddleware(RequestDelegate next, ILogger logger)
{
this.next = next;
this.logger = logger;
}
public async Task Invoke(HttpContext context)
{
try
{
await this.next.Invoke(context);
}
catch (Exception e)
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
}
}
}
我记得能够通过完整的 .NET 框架中提供的 Owin 测试服务器来执行此操作。有什么想法如何去做吗?
您可以使用 WebApplicationFactory:
public class BasicTests
: IClassFixture<WebApplicationFactory<RazorPagesProject.Startup>>
{
private readonly WebApplicationFactory<RazorPagesProject.Startup> _factory;
public BasicTests(WebApplicationFactory<RazorPagesProject.Startup> factory)
{
_factory = factory;
}
而不是通用类型 RazorPagesProject.Startup
使用您自己的项目进行测试。工厂将为您提供访问所需路线的选项,并测试它们是否按您的要求执行:
// Arrange
var client = _factory.CreateClient();
// Act
var response = await client.GetAsync("api/Values");
//
response.EnsureSuccessStatusCode(); // Status Code 200-299