Asp Net Core 集成测试 - 方法不允许响应
AspNet Core Integration test - MethodNotAllowed Response
我创建了一个带有 GET、POST、PUT 路由的 webapi 项目,在邮递员中 运行 没问题。但是当我进行集成测试时,只有 GET 和 POST 路由通过了。在集成测试中发出 PUT 请求时,它会抛出 MethodNotAllowed Error (405 - Method not allowed)。
系统:Ubuntu18.10
网络版本:2.2.100
任何 advice/direction 将不胜感激。
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
您是否将 Postman 传递的 Header 与您的测试所构建的进行了比较?我可以看到的一件事可能是您没有发送内容类型。
ContentType = "text/json"
我忘了 post 我的控制器。
// 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", ...
这解决了我的问题。
我创建了一个带有 GET、POST、PUT 路由的 webapi 项目,在邮递员中 运行 没问题。但是当我进行集成测试时,只有 GET 和 POST 路由通过了。在集成测试中发出 PUT 请求时,它会抛出 MethodNotAllowed Error (405 - Method not allowed)。
系统:Ubuntu18.10 网络版本:2.2.100
任何 advice/direction 将不胜感激。
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
您是否将 Postman 传递的 Header 与您的测试所构建的进行了比较?我可以看到的一件事可能是您没有发送内容类型。
ContentType = "text/json"
我忘了 post 我的控制器。
// 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", ...
这解决了我的问题。