title: TDD for Web API with NUnit, NSubtitute
body: <p>I'm still confused with some TDD concepts and how to do it correctly. I'm trying to use it implement for a new project using Web API. I have read a lot about it, and some article suggest NUnit as a testing framework and NSubstitute to mock the repository.</p>
  
  <p>What I don't understand is with NSubstitute we can define the expected result of what we want, is this valid if we want to validate our code logic?</p>
  
  <p>Let's say I have a controller like this with <code>Put</code> and <code>Delete</code> method:</p>
  
  <pre><code>[BasicAuthentication]
  public class ClientsController : BaseController
  {
     // Dependency injection inputs new ClientsRepository
     public ClientsController(IRepository&lt;ContactIndex&gt; clientRepo) : base(clientRepo) { }
  
   [HttpPut]
      public IHttpActionResult PutClient(string accountId, long clientId, [FromBody] ClientContent data, string userId = "", string deviceId = "", string deviceName = "")
      {
          var result = repository.UpdateItem(new CommonField()
          {
              AccountId = accountId,
              DeviceId = deviceId,
              DeviceName = deviceName,
              UserId = userId
          }, clientId, data);
  
          if (result.Data == null)
          {
              return NotFound();
          }
  
          if (result.Data.Value != clientId)
          {
              return InternalServerError();
          }
  
          IResult&lt;IDatabaseTable&gt; updatedData = repository.GetItem(accountId, clientId);
  
          if (updatedData.Error)
          {
              return InternalServerError();
          }
  
          return Ok(updatedData.Data);
      }
  
      [HttpDelete]
      public IHttpActionResult DeleteClient(string accountId, long clientId, string userId = "", string deviceId = "")
      {
          var endResult = repository.DeleteItem(new CommonField()
          {
              AccountId = accountId,
              DeviceId = deviceId,
              DeviceName = string.Empty,
              UserId = userId
          }, clientId);
  
          if (endResult.Error)
          {
              return InternalServerError();
          }
  
          if (endResult.Data &lt;= 0)
          {
              return NotFound();
          }
  
          return Ok();
      }
  
  }
  </code></pre>
  
  <p>and I create some unit tests like this:</p>
  
  <pre><code>[TestFixture]
      public class ClientsControllerTest
      {
          private ClientsController _baseController;
          private IRepository&lt;ContactIndex&gt; clientsRepository;
          private string accountId = "account_id";
          private string userId = "user_id";
          private long clientId = 123;
          private CommonField commonField;
  
          [SetUp]
          public void SetUp()
          {
              clientsRepository = Substitute.For&lt;IRepository&lt;ContactIndex&gt;&gt;();
              _baseController = new ClientsController(clientsRepository);
              commonField = new CommonField()
              {
                  AccountId = accountId,
                  DeviceId = string.Empty,
                  DeviceName = string.Empty,
                  UserId = userId
              };
          }
  
          [Test]
          public void PostClient_ContactNameNotExists_ReturnBadRequest()
          {
              // Arrange
              var data = new ClientContent
              {
                  shippingName = "TestShippingName 1",
                  shippingAddress1 = "TestShippingAdress 1"
              };
  
              clientsRepository.CreateItem(commonField, data)
                  .Returns(new Result&lt;long&gt;
                  {
                      Message = "Bad Request"
                  });
  
              // Act
              var result = _baseController.PostClient(accountId, data, userId);
  
              // Asserts
              Assert.IsInstanceOf&lt;BadRequestErrorMessageResult&gt;(result);
          }
  
          [Test]
          public void PutClient_ClientNotExists_ReturnNotFound()
          {
              // Arrange
              var data = new ClientContent
              {
                  contactName = "TestContactName 1",
                  shippingName = "TestShippingName 1",
                  shippingAddress1 = "TestShippingAdress 1"
              };
  
              clientsRepository.UpdateItem(commonField, clientId, data)
                  .Returns(new Result&lt;long?&gt;
                  {
                      Message = "Data Not Found"
                  });
  
              var result = _baseController.PutClient(accountId, clientId, data, userId);
              Assert.IsInstanceOf&lt;NotFoundResult&gt;(result);
          }
  
          [Test]
          public void PutClient_UpdateSucceed_ReturnOk()
          {
              // Arrange
              var postedData = new ClientContent
              {
                  contactName = "TestContactName 1",
                  shippingName = "TestShippingName 1",
                  shippingAddress1 = "TestShippingAdress 1"
              };
  
              var expectedResult = new ContactIndex() { id = 123 };
  
              clientsRepository.UpdateItem(commonField, clientId, postedData)
                  .Returns(new Result&lt;long?&gt; (123)
                  {
                      Message = "Data Not Found"
                  });
  
              clientsRepository.GetItem(accountId, clientId)
                  .Returns(new Result&lt;ContactIndex&gt;
                  (
                      expectedResult
                  ));
  
              // Act
              var result = _baseController.PutClient(accountId, clientId, postedData, userId)
                  .ShouldBeOfType&lt;OkNegotiatedContentResult&lt;ContactIndex&gt;&gt;();
  
              // Assert
              result.Content.ShouldBe(expectedResult);
          }
  
          [Test]
          public void DeleteClient_ClientNotExists_ReturnNotFound()
          {
              clientsRepository.Delete(accountId, userId, "", "", clientId)
                  .Returns(new Result&lt;int&gt;()
                  {
                      Message = ""
                  });
  
              var result = _baseController.DeleteClient(accountId, clientId, userId);
  
              Assert.IsInstanceOf&lt;NotFoundResult&gt;(result);
          }
  
          [Test]
          public void DeleteClient_DeleteSucceed_ReturnOk()
          {
              clientsRepository.Delete(accountId, userId, "", "", clientId)
                  .Returns(new Result&lt;int&gt;(123)
                  {
                      Message = ""
                  });
  
              var result = _baseController.DeleteClient(accountId, clientId, userId);
  
              Assert.IsInstanceOf&lt;OkResult&gt;(result);
          }
      }
  </code></pre>
  
  <p>Looking at the code above, am I writing my unit tests correctly? I feel like I'm not sure how it will validate the logic in my controller.</p>
  
  <p>Please ask for more information, if there is anything that needs clarified.</p>