如何正确地集成测试Web Api控制器与IEnumerable结果?

Vla*_*hek 4 c# linq asp.net asp.net-mvc

原始问题有点不正确,因为问题只发生在控制器测试期间如何在枚举IEnumerable失败时返回正确的状态代码.ASP.NET WebApi

问题是如何正确测试web api控制器,当IEnumerable在延迟执行期间可能抛出异常时,它返回IEnumerable?

例如,我有这样的API端点:

public class EntityController : ApiController
{
    ...
    public IHttpActionResult Get()
    {
        return Ok(Session.Query<Entity>());
    }
}
Run Code Online (Sandbox Code Playgroud)

无论在查询执行期间可能抛出异常,相应的测试都将始终通过.

[Test]
public async Task Test()
{
     var entityController = new EntityController(Session)
                {
                    Configuration = new HttpConfiguration(),
                    Request = new HttpRequestMessage()
                };

    var response = await entityController.GetAll().ExecuteAsync(new CancellationTokenSource().Token);

    response.EnsureSuccessStatusCode();
}
Run Code Online (Sandbox Code Playgroud)

但是,如果在控制器本身内部转换ToList,则此测试将不会通过.

public class EntityController : ApiController
{
    ...
    public IHttpActionResult Get()
    {
        return Ok(Session.Query<Entity>().ToList());
    }
}
Run Code Online (Sandbox Code Playgroud)

Ani*_*tel 7

在我看来,您希望创建集成测试来测试您的Web api端点.

您当前的测试不会遇到媒体类型格式化程序或可能发生问题的Web API管道的其他部分.

我建议在测试项目中使用Microsoft.Owin.Testing nuget包.这将允许您在内存中的Web服务器中设置Web api控制器以进行测试,这将涵盖更多的web api管道.

根据您的代码片段判断,您的web api控制器没有任何依赖关系,System.Web因此使用OWIN进行测试可能符合您的需求.当然,这不会涵盖任何特定于IIS设置的内容或Web api之外的IIS管道中的任何内容.但是,Linq query如果您不在ToList()控制器操作中使用它,它将捕获从延迟执行中抛出的异常.

要使用Owin和Owin测试,您需要按照以下步骤操作:

1.将Microsoft.Owin nuget包添加到包含您要测试的Web api控制器的Web项目中.

2.将Owin Startup类添加到该Web项目:

public class Startup {
    public virtual void Configuration(IAppBuilder builder) {
        // if you want to move all your web api initialization 
        // and configuration to here then you can. 
        // Otherwise just leave this method empty
    }
}
Run Code Online (Sandbox Code Playgroud)

我们将覆盖Configuration测试项目中的方法.

3.将Microsoft.AspNet.WebApi.Owin nuget包添加到测试项目中

4.将Microsoft.Owin.Testing nuget包添加到测试项目中.

5.在测试项目中创建一个Test类:

public class TestClass {
    private class TestStartup : Startup {
        public override void Configuration(IAppBuilder app) {
            // do your web api, IoC, etc setup here
            var config = new HttpConfiguration();
            config.MapHttpAttributeRoutes();
            // ...etc
            app.UseWebApi(config);
        }
    }

    [Test]
    public void MyTest() {
        // arrange
        using (var server = TestServer.Create<TestStartup>()) {

            // act
            var response = server.CreateRequest("api/someroute/").GetAsync().Result;

            // verify
            Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

确保TestStartup内部类派生自Startup第2步中在Web项目中创建的类,这将确保web api将从Web项目中获取控制器.还有其他方法,但这很简单,并且如果您使用Owin,则能够重用实际应用程序中的初始化代码.

6.利润