title: ASP .NET Core Integration Tests fails with corrupted body
body: <p>I'm working on a project where we have to develop a web API with ASP .NET Core 3.x. So far, so good, it is running well. Now, I'm writing some integration tests for this web API and I have some trouble to get the tests for everything else than GET request to work.</p>
  
  <p>We're using the Clean Architecture from Jason Taylor. This means we have a core project with all our request handler, a domain project with all database entities and a presentation project for the API controllers. We use <a href="https://github.com/jbogard/MediatR" rel="nofollow noreferrer">MediatR</a> and dependency injection for the communication between these projects.</p>
  
  <p>Now, we have the problem that the body data of the reuqest doesn't reach the controller.</p>
  
  <p>This is how the Update method in the controller looks like:</p>
  
  <pre class="lang-cs prettyprint-override"><code>[ApiController]
  [Route("api/[controller]/[action]")]
  public abstract class BaseController : ControllerBase
  {
      private IMediator _mediator;
      protected IMediator Mediator =&gt; _mediator ??= HttpContext.RequestServices.GetService&lt;IMediator&gt;();
  }
  
  public class FavoriteController : BaseController
  {
      [HttpPut("{id}")]
      [ProducesResponseType(StatusCodes.Status204NoContent)]
      [ProducesResponseType(StatusCodes.Status404NotFound)]
      public async Task&lt;IActionResult&gt; Update(long id, UpdateFavoriteCommand command)
      {
          if (command == null || id != command.Id)
          {
              return BadRequest();
          }
  
          // Sends the request to the corresponding IRequestHandler
          await Mediator.Send(command);
  
          return NoContent();
      }
  }
  </code></pre>
  
  <p>We use xUnit.net as test framework.
  For the integration tests, we're using an InMemory SQLite database which is setup in a fixture class.</p>
  
  <p>The test looks like the following:</p>
  
  <pre class="lang-cs prettyprint-override"><code>public class UpdateFavoritesTestSqlite : IClassFixture&lt;WebApplicationFactoryWithInMemorySqlite&lt;Startup&gt;&gt;
  {
      private readonly WebApplicationFactoryWithInMemorySqlite&lt;Startup&gt; _factory;
      private readonly string _endpoint;
  
      public UpdateFavoritesTestSqlite(WebApplicationFactoryWithInMemorySqlite&lt;Startup&gt; factory)
      {
          _factory = factory;
          _endpoint = "api/Favorite/Update/";
      }
  
      [Fact]
      public async Task UpdateFavoriteDetail_WithFullUpdate_ShouldUpdateCorrectly()
      {
          // Arange
          var client = _factory.CreateClient(); // WebApplicationFactory.CreateClient()
          var command = new UpdateFavoriteCommand
          {
              Id = 5,
              Caption = "caption new",
              FavoriteName = "a new name",
              Public = true
          };
  
          // Convert to JSON
          var jsonString = JsonConvert.SerializeObject(command);
          var httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json");
  
          var stringUri = client.BaseAddress + _endpoint + command.Id;
          var uri = new Uri(stringUri);
  
          // Act
          var response = await client.PutAsync(uri, httpContent); 
          response.EnsureSuccessStatusCode();
          httpContent.Dispose();
  
          // Assert
          response.StatusCode.ShouldBe(HttpStatusCode.NoContent);
  
      }
  }
  </code></pre>
  
  <p>If we run the test, we get an 400 Bad Request error.
  If we run the test in Debug mode, we can see that the code throws a custom ValidationException because of a model state error. This is configured in the DependencyInjection of the presentation project:</p>
  
  <pre class="lang-cs prettyprint-override"><code>services
      .AddControllers()
      .ConfigureApiBehaviorOptions(options =&gt;
      {
          options.InvalidModelStateResponseFactory = context =&gt;
          {
              var failures = context.ModelState.Keys
                  .Where(k =&gt; ModelValidationState.Invalid.Equals(context.ModelState[k].ValidationState))
                  .ToDictionary(k =&gt; k, k =&gt; (IEnumerable&lt;string&gt;)context.ModelState[k].Errors.Select(e =&gt; e.ErrorMessage).ToList());
  
              throw new ValidationException(failures);
          };
      })
      .AddFluentValidation(fv =&gt; fv.RegisterValidatorsFromAssemblyContaining&lt;IWebApiDbContext&gt;());
  </code></pre>
  
  <p>The failures object contains one error which says:</p>
  
  <pre><code>The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
  </code></pre>
  
  <p>Here is a screenshot: <a href="https://i.stack.imgur.com/JUeiI.jpg" rel="nofollow noreferrer">Visual Studio in Debugging mode with json error.</a></p>
  
  <p>In one article in stackoverflow I've read, that removing the <code>[ApiController]</code> class attribute can result in a more detailed error description. During debugging again the test and setting a breakpoint int the Update method from the FavoriteController at the line with <code>await Mediator.Send(command);</code>, I was able to see, that the command object arriving the Update method contains only null or default values, except the id, which was 5.</p>
  
  <pre><code>command 
      Caption         null    string
      FavoriteName    null    string
      Id              5       long
      Public          false   bool
  </code></pre>
  
  <p>The most confusing (and frustrating) part is, that a manual test with swagger or postman are both successfull. The way I understand it, there has to be a problem during the integration test.</p>
  
  <p>I hope, someone can help me and see what I'm missing. Could it be possible that there is something wrong with the HttpClient of the Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory?</p>