Search code examples
c#asp.net-coreintegration-testingasp.net-core-2.2

AspNet Core Integration test - MethodNotAllowed Response


I have created a webapi project with GET, POST, PUT routes which run fine in the postman. But when I've made integration test, only GET and POST routes are passing. When making PUT request in integration test, it throws MethodNotAllowed Error (405 - Method not allowed).

System: Ubuntu 18.10 dotnet version: 2.2.100

Any advice/direction would be much appreciated.

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>

Console output:

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 

Solution

  • I forgot to post my controller.

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

    So there is defined an ID parameter for that action, but in the integration test it's missing. It should be:

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

    That resolved my issue.