lokanath das
lokanath das

Reputation: 916

Unit test for Exception secario using Mock

I have a API, where the Return type is IActionResult. Pseudo Code as below

public async Task<IActionResult> Getdata()
{
   var result = await _report.Getall(DateTime.UtcNow);
}

I am trying to write Unit test for this as below.

[Test]
public async Task Error_code()
{
    _report.Setup(r => r.Getall(It.IsAny<DateTime>())).ThrowsAsync(new Exception("Error Message"));
    var result = await _reportCnt.Getdata(); //_reportCnt is object of the Controller
    Assert.AreEqual("Error Message",reuslt);
}

But the issue i am facing is, Once the Error is thrown from the API, its not going to Assert, It's failing the Unit test with Error Exception of type 'System.Exception' was thrown.

I have tried these 3 ways

var result = await _reportCnt.Getdata() as ObjectResult;
var result = await _reportCnt.Getdata() as ActionResult;
var result = await _reportCnt.Getdata() as ExceptionResult;

but not working, throwing the same issue.

Anything i am missing here or any suggestion?

Upvotes: 0

Views: 2375

Answers (2)

Ogglas
Ogglas

Reputation: 70184

This is an example testing the default WeatherForecastController returning ActionResult instead of IActionResult. You can read about the benefits here:

https://learn.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-5.0#actionresultt-type

[Authorize]
[ApiController]
[Route("[controller]")]

public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public ActionResult<IEnumerable<WeatherForecast>> Get()
    {
        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

Test using xUnit but you should be abele to convert to NUnit.

[Fact]
public void DummyTest()
{
    var logger = Mock.Of<ILogger<WeatherForecastController>>();
    var controller = new WeatherForecastController(logger);

    var result = controller.Get().Value.First();

    Assert.True(result.Date.Date == DateTime.Now.AddDays(1).Date, "Date is current date");

    Assert.Throws<ArgumentOutOfRangeException>(() => controller.Get().Value.ToList()[5]);
}

Upvotes: -1

Mitul&#225;t b&#225;ti
Mitul&#225;t b&#225;ti

Reputation: 2166

After you have setup your mock to throw an exception you can expect that by invoking the method under test like this:

[Test]
public void Test1()
{
    _report.Setup(r => r.Getall(It.IsAny<DateTime>())).ThrowsAsync(new Exception("Error Message"));

    var exceptionThrown = Assert.ThrowsAsync<Exception>(async () => await _reportCnt.Getdata());

    Assert.AreEqual("Error Message", exceptionThrown.Message);
}

Upvotes: 2

Related Questions