单元测试以确保只有选定的HTTP谓词适用于WebAPI

时间:2014-02-03 12:16:49

标签: c# unit-testing asp.net-mvc-4 asp.net-web-api asp.net-web-api-helppages

使用WebAPI。

我们创建的一个测试是确保对于特定的控制器,只允许GET动词。

编写了一个使用MVC HelpPages的测试

HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(baseAddress);
config.Routes.MapHttpRoute(
    "SearchAPI", 
    "api/{controller}/{id}");

HttpSelfHostServer server = new HttpSelfHostServer(config);
server.OpenAsync().Wait();
IApiExplorer apiExplorer = config.Services.GetApiExplorer();
var apiDescriptions = apiExplorer.ApiDescriptions;
var data = from description in apiDescriptions
           where description.ActionDescriptor.ControllerDescriptor.ControllerType.FullName.StartsWith("MySite.Presentation.Pages.SearchAPI")
           orderby description.RelativePath
           select description
           ;
foreach (var apiDescription in data)
{
    Assert.That(apiDescription.HttpMethod, Is.EqualTo(HttpMethod.Get), string.Format("Method not Allowed: {0} {1}", apiDescription.RelativePath, apiDescription.HttpMethod));
}

现在进行此测试虽然它可能不是确保我们的控制器的最佳方法,但只有适用的GET HTTP VERB方法才有效。

我们现在已升级到MVC5,此测试现已失败。由于HttpSelfHostServer不再可用

查看Microsoft的msdn库,不建议您使用HttpSelfHostServer,而是鼓励使用Owin。

我已经开始使用新的Owin课程了

public class OwinStartUp
{
    public void Configuration(IAppBuilder appBuilder)
    {
        var config = new HttpConfiguration();
        config.Routes.MapHttpRoute(
            name: "SearchAPI",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        AreaRegistration.RegisterAllAreas();
        appBuilder.UseWebApi(config); 
    }
}

但是当谈到测试时,这就是我能够得到的

        string baseAddress = "http://localhost/bar";
        using (var server = WebApp.Start<OwinStartUp>(url: baseAddress))
        {


        }

我不知道如何从配置中访问服务,然后能够调用GetApiExplorer方法,因为Intellisense建议的服务器变量上没有公共方法。

我一直在寻找一些展示如何使用Owin的网站,但他们没有帮助我解决这个问题: http://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api

还存在这些问题 Can't get ASP.NET Web API 2 Help pages working when using Owin 但这并没有帮助我解决问题。

我需要做什么,能够编写单元测试以确保控制器/方法只允许特定的HTTP VERBS,或者如何配置Owin以使用API​​ HelpPages

2 个答案:

答案 0 :(得分:4)

对于您的场景,您不需要启动服务器,例如,您可以执行以下操作来获取api描述。请注意,为了获取api描述,api explorer不需要执行实际请求来获取apidecription。

var config = new HttpConfiguration();

config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

IApiExplorer explorer = config.Services.GetApiExplorer();

var apiDescs = explorer.ApiDescriptions;

答案 1 :(得分:0)

我有一个使用XUnit的.NET Core 3.1测试项目,该项目可以测试ASP.NET MVC项目。以下测试可确保所有控制器都有与其关联的HTTP动词(例如,没有忘记添加一个或多个)。这个问题帮助我到达了那里,所以我将测试发布在这里:

[Fact]
public void Controllers_All_Have_Http_Verbs()
{
  var methodsMissingHttpVerbs = Assembly
    .GetAssembly(typeof(HomeController)).GetTypes()
    .Where(type => typeof(Controller).IsAssignableFrom(type))
    .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
    .Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), true).Any())
    .Count(c => c.GetCustomAttribute<HttpGetAttribute>() == null &&
                c.GetCustomAttribute<HttpPostAttribute>() == null &&
                c.GetCustomAttribute<HttpDeleteAttribute>() == null);

  Assert.Equal(0, methodsMissingHttpVerbs);
}