locked
what all should be unit tested in asp.net core web Api RRS feed

  • Question

  • User1838940990 posted

    Hi Team,

    I was not using TDD and unit testing  earlier, now I am planning to include usniteting to exiting code and TDD for new modules.

    Below code I have a controller  accepts object  on post request and then call a service to call another third party  api to fetch some details .

    some times we do some formatting before passing to apui as well 

    which are all the components I need to test in this 

    do I have test for formatting method 

    and method for testing whether the api is returning results or no based on the sample data. I am going to use Moq and XUnit for testing , wrote some test as well. but 

    Please advise me on this . Below is the sample code for my controller and service 

    thanks 

    [Route("[controller]")]
    [ApiController]
    public class MyController : ControllerBase
    {
       private readonly ILogger<MyController> _logger;
       private readonly IPriceService _priceService;
       MyController(ILogger<MyController> logger, IPriceService priceService)
       {
       _priceService = priceService;
        _logger = logger;
       }
       
       
        
            [Route("price")]
            public IActionResult GetPrice(items items)
            {
          
                try
                {
    			    
    	        var formattedItems = _priceService.Format(items);
                    var response = _priceService.GetPrice(formattedItems);
                   
                }
                catch (Exception ex)
                {
                    _logger.LogError("Exception occured in GetPrice {0} ", ex.Message);
                   return StatusCode(StatusCodes.Status500InternalServerError, ex.GetBaseException().Message);
    
                }
                return Ok(response);
            }
       
     }
     
     public class PriceService : IPriceService
     {
     
     public PriceList GetPrice(items items)
     {
     //calling a third party api using the  basic authentication here 
     
      var httpClient = _httpClientFactory.CreateClient("Price");
    
    
    var response = await  httpClient.SendAsync(httpPostMessage);
    
    return response;
    }
    
    
    public ItemList Format(items items)
     {
    //do some formatting a retrurn the resutls 
    
    return formatted ITems;
    }
    

    Monday, March 8, 2021 4:17 AM

All replies

  • User1120430333 posted

    IMHO, what you should  be trying to UT is the priceservice.GetPrice() that should be mocked out along with a mocking out httpclient being used in priceservice.GetPrice(), which should be tested  by a unitest classlib project  with a unit testing class method that is using moq and xunit to unit test the method in the PriceService object.

    Unit Test and Mock Typed HttpClient using HttpClientFactory in .NET Core (thecodebuzz.com)

    You also mock out calls to external resources during a unit test.

    The Format() should run in the unittest class as a method() to make some fake/mock data that will be sent into mocking out of  priceservice.GetPrice() on the 'actual' return of data when the actual running of the test on the method is done.

    A Set of Unit Testing Rules (artima.com)

    Arrange-Act-Assert: A Pattern for Writing Good Tests | Automation Panda

    Arrange

    set up fake/mocked data to be sent into a method to be tested and return of data out of the tested method.

    setup all mocks need in the testing of the method to be tested along with the mock data to be returned out of the actual testing of mocked object's method.

    Act

    actually run the test on the object's method execute the method.

    Assert

    verify that the test worked as expected.

    Pattern of the Month: Red Green Refactor - DZone Agile

    You don't need a try/catch in code in the WebAPI or code it references if you implement Global Exemption Handling in the WebAPI project like the ErrorHandingFilter.cs you can examine in the WebAPI project out on Github. It's a little different implementation of GEH for a Core WebApi as opposed to a non Core WebAPI depicted in the link.

    How to Catch All Exceptions in C# & Find All Application Errors – Stackify

    darnold924/PublishingCompany (github.com)

    HTH

    Monday, March 8, 2021 9:00 AM
  • User1838940990 posted

    Thanks for your quick and detailed reply .

    special thanks for pointing out the exception handling 

    sorry to raise one more question .

    I know the question I am asking you is because of lack of knowledge of unit testing concepts, but unfortunately I am on a deadline  and same time so eager to incorporate TDD, please ignore if it is dump question.

    Let me tell you what I understood from the above 

    1, for priceservice() method, need to mock the httpclient and instead of calling the external api , I need to mock the call and return a mock result as response,

    2, for Format method , I need to pass a dummy object and execute the actual format method to verify the result is fine or not 

    then how do we test the real external api call ? 

    so here we executing only the  format method  ?

    thanks once again

    Tuesday, March 9, 2021 10:58 PM
  • User475983607 posted

    techasuran

    1, for priceservice() method, need to mock the httpclient and instead of calling the external api , I need to mock the call and return a mock result as response,

    No.  A unit test tests logic that operates on data.  There is no need to mock HttpClient, just the data HttpClient returns.   Typically that data is returned by a service.  The service is mocked and the data is mocked to suite your test cases. 

    techasuran

    then how do we test the real external api call ? 

    There is no need to test an external API call.  We know that works.  You create a new API and pass the mocked interfaces to the API constructor. 

    I recommend going through TDD tutorials rather than guessing.

    Tuesday, March 9, 2021 11:39 PM
  • User1120430333 posted

    1, for priceservice() method, need to mock the httpclient and instead of calling the external api , I need to mock the call and return a mock result as response,

    Yes, the mock data will be what you created in the Arrange for the response on Mock.Return(fackresponse) for a given mock of an object 

     for Format method , I need to pass a dummy object and execute the actual format method to verify the result is fine or not 

    The Format() is executed to make some fakeresponse data in the Arrange  to be used on the  Mock.Return(fackresponse) for object's method that is being UT that returns a response.

    then how do we test the real external api call ? 

    UT-ing is about  not doing anything for real simply put. I gave you a link on When a test is not a Unit Test. You should understand it, which a test that goes across a network no matter if it's a LAN or WAN/Internet is not a unit test.

    You want to test everything for real including the external API making sure everything works correctly, then you do a integration test using a claalib project, a class with a testmethod,  that is using nunit, with using a test harness like MSTest or one of the other UT harnesses and test the method for real. 

    Pluralsight has several TDD and UT courses, which has a monthly rate $35.  You signup and take the classes or as many classes on other subjects you can take in a month. A lot of developers want to do UT, think they know how to do it, but they don't It's that simple. You should make your company pay for training that will help you in your job.

    Wednesday, March 10, 2021 12:54 AM