title: ASP.Net Web API Controller Unit Test POST
body: <p>I am new to Unit Testing and am trying to create some Xunit tests for my Web API Controller's <code>POST</code> method.</p>
  
  <p>Here is my Controller's <code>POST</code> method:</p>
  
  <pre><code>[HttpPost("")]
  public async Task&lt;IActionResult&gt; CreateArea([FromBody] AreaForCreationDto area)
  {
      // Check that the 'area' object parameter can be de-serialised to a AreaForCreationDto.
      if (area == null)
      {
          var message = "Could not de-serialise the request body to an AreaForCreationDto object";
          _logger.LogError(message);
  
          // Return an error 400.
          return BadRequest(message);
      }
  
      /*
       * ModelState.IsValid is determined by the attributes associated with the 
       * Data Annotations on the properties of the ViewModel.
       */
      if (!ModelState.IsValid)
      {
          // Return a response with a Status Code 422.
          return new UnprocessableEntityObjectResult(ModelState);
      };
  
      // Map a AreaForCreationDto object to a Area entity.
      var areaEntityToAdd = _mapper.Map&lt;Area&gt;(area);
  
      // Call the repository to add the new Area entity to the DbContext.
      _areaRepository.AddArea(areaEntityToAdd);
  
      // Save the new Area entity, added to the DbContext, to the SQL database.
      if (await _areaRepository.SaveChangesAsync())
      {
          // Note: AutoMapper maps the values of the properties from the areaEntityToAdd
          // to a new areaToReturn object.
          // This ensures that we don't expose our Area entity to the web browser.
          var areaToReturn = _mapper.Map&lt;AreaDto&gt;(areaEntityToAdd);
  
          // Return a 201 'created' response along with the location URL in the
          // response Header.
          return CreatedAtRoute("GetArea",
              new { id = areaToReturn.Id },
              areaToReturn);
      }
      else {
          // The save failed.
          var message = $"Could not save new Area {areaEntityToAdd.Id} to the database.";
          _logger.LogWarning(message);
          throw new Exception(message);
      };
  }
  </code></pre>
  
  <p>The first Unit Test I have written is intended to ensure that on sending a POST request, with an object which can be de-serialised into an <code>AreaForCreation</code> object, the function returns a <code>201 CreatedAtRouteResult</code> along with the new Area which has been created.</p>
  
  <p>Here is the Xunit test:</p>
  
  <pre><code>[Fact]
  public void ReturnAreaForCreateArea()
  {
      //Arrange
  
      var _mockAreaRepository = new Mock&lt;IAreaRepository&gt;();
      _mockAreaRepository
          .Setup(x =&gt; x.AddArea(testArea));
  
      var _mockMapper = new Mock&lt;IMapper&gt;();
      _mockMapper
          .Setup(_ =&gt; _.Map&lt;Area&gt;(It.IsAny&lt;AreaForCreationDto&gt;()))
          .Returns(testArea);
  
      var _mockLogger = new Mock&lt;ILogger&lt;AreasController&gt;&gt;();
      var _sut = new AreasController(_mockAreaRepository.Object, _mockLogger.Object, _mockMapper.Object);
  
      // Act
      var result = _sut.CreateArea(testAreaForCreationDto);
  
      // Assert
      Assert.NotNull(result);
      var objectResult = Assert.IsType&lt;CreatedAtRouteResult&gt;(result);
      var model = Assert.IsAssignableFrom&lt;AreaDto&gt;(objectResult.Value);
      var areaDescription = model.Description;
      Assert.Equal("Test Area For Creation", areaDescription);
  }
  </code></pre>
  
  <p>I am getting an exception thrown when the unit test tries to <code>Assert.IsType&lt;CreatedAtRouteResult&gt;(result)</code>. Debugging revealed that the Controller was failing to save to the repository. My <code>AreaRepository</code> has the following AddArea function which does not return a value so I assume that my <code>_mockAreaRepository</code> does not require a <code>Return</code> condition set (could be wrong here).</p>
  
  <p>Do I need to configure my <code>mockAreasRepository</code> for the outcome of calling <code>SaveChangesAsync()</code>?</p>