> UpdateWeatherForec" /> > UpdateWeatherForec" /> > UpdateWeatherForec"/>

How to define the result of a Task<int> test with Xunit

37 Views Asked by At

one of my first atempts of testing with XUnit. I need to test this API:

[HttpPut("Update")]
public async Task<ActionResult<string>> UpdateWeatherForecast([FromBody] WeatherForecast weatherForecast)
    {
       var exist= await _euroNextService.UpdateAsync(weatherForecast.Date, weatherForecast);
        if (exist==0  )
        {
            return BadRequest();
        }
        return NoContent();
    }

This the test I have so far:

 [Fact]
  public async Task TestUpdateReturnsNoResult()
  {
      // Arrange
      var euroNextServiceMock = new Mock<IEuronextService>();
      var loggerMock = new Mock<ILogger<WeatherForecastController>>();
 
      WeatherForecast forecast = new WeatherForecast() { Date = new DateOnly(2024, 3, 16), TemperatureC = 20 };
      DateOnly date = new DateOnly(2024, 3, 13);
    var tst=  euroNextServiceMock.Setup(r => r.UpdateAsync(date, forecast) ).ReturnsAsync(1); //here it returns 0

      // Act 
      var controller = new WeatherForecastController(loggerMock.Object, euroNextServiceMock.Object);
      var result = await controller.UpdateWeatherForecast(forecast);

      //Assert
      Assert.IsType<NoContentResult>(result.Result);
  }

with forecast defined as :

public class WeatherForecast
    {
        [Required, Key]
        public DateOnly Date { get; set; }

        [Required]
        public int TemperatureC { get; set; }
    }

and ExecuteUpdateAsync:

      public async Task<int> UpdateAsync(DateOnly date, WeatherForecast weatherForecast)
       { 
         return await _appDbContext.WeatherForecasts.Where(x => x.Date == date).ExecuteUpdateAsync(setters=>setters
           .SetProperty(s=>s.TemperatureC, weatherForecast.TemperatureC));
       }

how can I have euroNextServiceMock returns 1 or any result but 0? It mocks the result of an ExecuteUpdateAsync and should return the rows updated.

1

There are 1 best solutions below

1
Luke Woodward On

You are telling your euroNextServiceMock to return 1 if it is given the date 16th March 2024 and the forecast object.

During your test you then call your controller with the date of 13th March 2024 and the forecast object. The controller method then calls the euroNextService mock with these values.

Of course, the mock hasn't been told what value to return if it is given the date 13th March 2024 and forecast, so it returns 0, because that's the default int value.

Change both dates in your test to be the same, and you should find your test passes.