【问题标题】:Using TestServer for error scenarios使用 TestServer 处理错误场景
【发布时间】:2018-07-25 07:30:21
【问题描述】:

我正在尝试使用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 :发生一个或多个错误。 (方法 或操作未执行。)

如果我要在管道开始时插入一些自定义中间件,我可以让它工作,类似于这样:

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 测试服务器来执行此操作。任何想法如何去做?

【问题讨论】:

    标签: c# unit-testing asp.net-core .net-core integration-testing


    【解决方案1】:

    你可以使用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
    

    【讨论】:

    • 刚试过这个,我得到错误 System.InvalidOperationException : No method 'public static IWebHostBuilder CreateWebHostBuilder(string[] args)' found on 'AutoGeneratedProgram'。或者,可以扩展 WebApplicationFactory1 并覆盖“受保护的虚拟 IWebHostBuilder CreateWebHostBuilder()”以提供您自己的 IWebHostBuilder 实例。有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    相关资源
    最近更新 更多