私はASP.NET Core WebAPIを構築中です。コントローラーの単体テストを作成しようとしています。私が見つけたほとんどの例は、古いWebAPI/WebAPI2プラットフォームのものであり、新しいCoreコントローラーとは関係がないようです。
私のコントローラーメソッドはIActionResults
を返しています。ただし、IActionResult
オブジェクトには、コントローラーコンテキストを必要とするExecuteResultAsync()
メソッドしかありません。コントローラーを手動でインスタンス化しているため、このインスタンスのコントローラーコンテキストはnullであり、ExecuteResultAsync
を呼び出すと例外が発生します。基本的にこれは、これらのユニットテストを正常に完了させるための非常にハックな方法に導かれ、非常に面倒です。私は、APIコントローラーをテストするためのより単純で正しい方法がなければならないと疑問に思っています。
また、それが違いを生む場合、私のコントローラーはasync/awaitを使用していません。
私が達成しようとしているものの簡単な例:
コントローラー方式:
[HttpGet(Name = "GetOrdersRoute")]
public IActionResult GetOrders([FromQuery]int page = 0)
{
try
{
var query = _repository.GetAll().ToList();
int totalCount = query.Count;
int totalPages = (int)Math.Ceiling((double)totalCount / pageSize) - 1;
var orders = query.Skip(pageSize * page).Take(pageSize);
return Ok(new
{
TotalCount = totalCount,
TotalPages = totalPages,
Orders = orders
});
}
catch (Exception ex)
{
return BadRequest(ex);
}
}
単体テスト:
[Fact]
public void GetOrders_WithOrdersInRepo_ReturnsOk()
{
// arrange
var controller = new OrdersController(new MockRepository());
// act
IActionResult result = controller.GetOrders();
// assert
Assert.Equal(HttpStatusCode.OK, ????);
}
のようなものを想定
public IActionResult GetOrders() {
var orders = repository.All();
return Ok(orders);
}
この場合のコントローラーは OkObjectResult
クラスを返します。
結果をメソッドで返すものの型にキャストし、それに対してアサートを実行します
[Fact]
public void GetOrders_WithOrdersInRepo_ReturnsOk() {
// arrange
var controller = new OrdersController(new MockRepository());
// act
var result = controller.GetOrders();
var okResult = result as OkObjectResult;
// assert
Assert.IsNotNull(okResult);
Assert.AreEqual(200, okResult.StatusCode);
}
次のようなクールなこともできます。
var result = await controller.GetOrders();//
var okResult = result as ObjectResult;
// assert
Assert.NotNull(okResult);
Assert.True(okResult is OkObjectResult);
Assert.IsType<TheTypeYouAreExpecting>(okResult.Value);
Assert.Equal(StatusCodes.Status200OK, okResult.StatusCode);
ありがとう