使用 Mock 对 Exception secario 进行单元测试
Unit test for Exception secario using Mock
我有一个 API,其中 Return 类型是 IActionResult
。伪代码如下
public async Task<IActionResult> Getdata()
{
var result = await _report.Getall(DateTime.UtcNow);
}
我正在尝试为此编写单元测试,如下所示。
[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);
}
但我面临的问题是,一旦从 API 中抛出错误,它就不会断言,单元测试失败并显示错误 Exception of type 'System.Exception' was thrown
.
这3种方法我都试过了
var result = await _reportCnt.Getdata() as ObjectResult;
var result = await _reportCnt.Getdata() as ActionResult;
var result = await _reportCnt.Getdata() as ExceptionResult;
但不工作,抛出同样的问题。
我在这里遗漏了什么或有什么建议吗?
这是一个测试默认 WeatherForecastController
返回 ActionResult
而不是 IActionResult
的示例。您可以在此处了解这些好处:
[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();
}
}
使用 xUnit
进行测试,但您应该能够转换为 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]);
}
在你设置你的 mock 以抛出异常之后,你可以期望通过像这样调用被测方法:
[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);
}
我有一个 API,其中 Return 类型是 IActionResult
。伪代码如下
public async Task<IActionResult> Getdata()
{
var result = await _report.Getall(DateTime.UtcNow);
}
我正在尝试为此编写单元测试,如下所示。
[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);
}
但我面临的问题是,一旦从 API 中抛出错误,它就不会断言,单元测试失败并显示错误 Exception of type 'System.Exception' was thrown
.
这3种方法我都试过了
var result = await _reportCnt.Getdata() as ObjectResult;
var result = await _reportCnt.Getdata() as ActionResult;
var result = await _reportCnt.Getdata() as ExceptionResult;
但不工作,抛出同样的问题。
我在这里遗漏了什么或有什么建议吗?
这是一个测试默认 WeatherForecastController
返回 ActionResult
而不是 IActionResult
的示例。您可以在此处了解这些好处:
[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();
}
}
使用 xUnit
进行测试,但您应该能够转换为 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]);
}
在你设置你的 mock 以抛出异常之后,你可以期望通过像这样调用被测方法:
[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);
}