Xunit test a method that calls web API Action method with parameters

61 Views Asked by At

I have a .Net core Blazor WASM which performs mathematical calculations. I have a method which passes some calculated values to the Web API method as parameters.

For eg.

public class Calculator
{
    private readonly HttpClient _client;
    public CalculatorService(HttpClient client)
    {
        _client = client;
    }

    public async Task<Decimal> CalculateValuesAsync(int a, int b, int entry)
    {
         decimal calc = (a * 100) / b;
         decimal ratio = entry / 5000;
         decimal result = GetRatio(calc, ratio);
         return result;
    }

    private decimal GetRatio(decimal calc, decimal ratio)
    {
        string uri = new($"api/GroupRatio?CalcRes={roundedValue }&entryRatio={ratio}");      
        var response = await _client.GetAsync(uri);
    
        var json = await response.Content.ReadAsStringAsync();
        var GroupRatio = JsonConvert.DeserializeObject<ExpectedGroupRatio>(json);
         
        if (GroupRatio != null)
             return GroupRatio;   
    }
}

This is the Web API Action method. The Web API performs a simple database call using EF core context class which uses the parameters to filter data from Database.

[HttpGet]
public async Task<IActionResult> GroupRatio(decimal CalcRes, decimal entryRatio)
{
    var lGroups = await _ctx.ExpectedGroupsRatios.Where(g => g.Group == CalcRes).OrderBy(x=>x.EntryRatio).ToListAsync();          

    decimal ratio = Math.Round(entryRatio, 2);
    var lossGroup = lGroups .FirstOrDefault(g => g.EntryRatio >= ratio);         

    return Ok(lossGroup);
}

Unit Test:

[Theory]
[InlineData(10, 20, 30)]
public async Task CalculateAsync_Test(int a, int b, int entry)
{ 
    var handler = new Mock<HttpMessageHandler>();
    HttpResponseMessage mockData = new HttpResponseMessage()
    {
        Content = JsonContent.Create(ExpectedGroupsRatios())
        *//ExpectedGroupsRatios() returns a list of all data (same as database table)*
    };
    

    handler.Protected().Setup<Task<HttpResponseMessage>>("SendAsync", 
      ItExpr.Is<HttpRequestMessage>(rm => rm.RequestUri.AbsoluteUri.EndsWith("api/GroupRatio")), 
      ItExpr.IsAny<CancellationToken>()).ReturnsAsync(mockData);


    var result = await _calculator.CalculateValuesAsync(a,b,entry);
    Assert.NotNull(result);
}

Currently, my mock API response contains all the table rows. But the method under test calls the API method with calculated values as parameters.

How do I unit test this method and mock the API response that has filtered data (and not all rows)?

0

There are 0 best solutions below