3

使用 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

4

2 回答 2

4

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

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;
于 2014-02-04T00:59:18.600 回答
0

我有一个使用 XUnit 测试 ASP.NET MVC 项目的 .NET Core 3.1 测试项目。以下测试确保所有控制器都有一个与之关联的 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);
}
于 2020-07-06T21:06:59.483 回答