【问题标题】:AspNet Core Integration test - MethodNotAllowed ResponseAspNet 核心集成测试 - MethodNotAllowed 响应
【发布时间】:2019-05-18 23:42:29
【问题描述】:

我创建了一个带有 GET、POST、PUT 路由的 webapi 项目,这些路由在邮递员中运行良好。但是当我进行集成测试时,只有 GET 和 POST 路由通过。在集成测试中发出 PUT 请求时,它会抛出 MethodNotAllowed Error (405 - Method not allowed)。

系统:Ubuntu 18.10 dotnet 版本:2.2.100

任何建议/方向将不胜感激。

namespace TestingMvc.Tests {
public class JsonContent : StringContent {
    public JsonContent (object obj):
        base (JsonConvert.SerializeObject (obj), Encoding.UTF8, "application/json") { }
}

public class MyTest : IClassFixture<WebApplicationFactory<WebApi.Startup>> {
    private readonly WebApplicationFactory<WebApi.Startup> _factory;

    public MyTest (WebApplicationFactory<WebApi.Startup> factory) {
        _factory = factory;
    }

    // This is Ok -> Returns 200
    [Fact]
    public async Task Get_Attachments () {
        var client = _factory.CreateClient ();
        var response = await client.GetAsync ("/attachments");
        Assert.Equal (HttpStatusCode.OK, response.StatusCode);
    }

    // This is Ok -> returns 200
    [Fact]
    public async Task Post_Attachments () {
        var client = _factory.CreateClient ();
        var response = await client.PostAsync ("/attachments", new JsonContent(new { a = "foobaz" }));
        Assert.Equal (HttpStatusCode.OK, response.StatusCode);
    }

    // This is not ok -> returns 405 Method not allowed
    [Fact]
    public async Task Put_Attachments () {
        var client = _factory.CreateClient ();
        var response = await client.PutAsync ("/attachments", new JsonContent(new { a = "foobaz" }));
        Assert.Equal (HttpStatusCode.OK, response.StatusCode);
    }
}
}

Startup.cs

    public void ConfigureServices (IServiceCollection services) {
        services.AddCors ();
        services.AddMvc ().SetCompatibilityVersion (CompatibilityVersion.Version_2_2);
    }

    public void Configure (IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
        app.ConfigureExceptionHandler ();
        app.UseCors (x => x
            .AllowAnyOrigin ()
            .AllowAnyMethod ()
            .AllowAnyHeader ()
            .AllowCredentials ());
        app.UseMvc ();
    }

WebApiTest.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <IsPackable>false</IsPackable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="2.2.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
    <PackageReference Include="xunit" Version="2.2.0" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="../src/WebApi.csproj" />
</ItemGroup>
</Project>

控制台输出:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/2.0 PUT http://localhost/attachments application/json; charset=utf-8 
dbug: TestingMvc.Tests.TestAuthenticationHandler[8]
      AuthenticationScheme: Test Scheme was successfully authenticated.
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '405 HTTP Method Not Supported'
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '405 HTTP Method Not Supported'
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 236.9092ms 405 

【问题讨论】:

  • 你为什么要经过一个空的身体?
  • 我正在传递附件正文对象。对不起,我已经更新了问题。添加了新的 { a = "foobaz" }
  • attachments 操作的定义是什么?它接受Put 方法吗?
  • 是的,确实如此。 PUT 请求在邮递员中有效,但我正在努力进行集成测试。

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


【解决方案1】:

我忘记发布我的控制器了。

    // PUT Attachments/someguid
    [HttpPut ("{id}")]
    public ActionResult<AttachmentDto> Put (Guid id, [FromBody] AttachmentDto attachment) {
        return Ok (_attachmentService.CreateOrUpdate (id, attachment));
    }

因此,为该操作定义了一个 ID 参数,但在集成测试中缺少它。应该是:

var response = await client.PutAsync ("/attachments/01D7ACA3-575C-4E60-859F-DB95B70F8190", ...

这解决了我的问题。

【讨论】:

    【解决方案2】:

    您是否将 Postman 通过的 Header 与您的测试构建的 Header 进行了比较?我可以看到的一件事可能是问题是您没有发送内容类型。

    ContentType = "文本/json"

    【讨论】:

    • 内容类型为application/json。 POST 请求没问题,但只有 PUT(也可能是 DELETE)不行。我已经用控制台输出更新了问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多