コンテンツにスキップ

C# ASP.NET Core Controllerの単体テスト

xUnitの調査
「ASP.NET Core でコントローラーのロジックの単体テストを行う」のチュートリアル

サンプルプロジェクトをダウンロード

リンク先から落とす

テスト対象のコントローラ

Task<IActionResult> Indexメソッドをテスト対象とする
テスト対象は_sessionRepository(DIされたモック)のメソッドを実行する

public class HomeController : Controller
{
    private readonly IBrainstormSessionRepository _sessionRepository;

    // 依存関係の注入 (DI)
    public HomeController(IBrainstormSessionRepository sessionRepository)
    {
        _sessionRepository = sessionRepository;
    }

    public async Task<IActionResult> Index()
    {
        var sessionList = await _sessionRepository.ListAsync();

        var model = sessionList.Select(session => new StormSessionViewModel()
        {
            Id = session.Id,
            DateCreated = session.DateCreated,
            Name = session.Name,
            IdeaCount = session.Ideas.Count
        });

        return View(model);
    }

    public class NewSessionModel
    {
        [Required]
        public string SessionName { get; set; }
    }

    [HttpPost]
    public async Task<IActionResult> Index(NewSessionModel model)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        else
        {
            await _sessionRepository.AddAsync(new BrainstormSession()
            {
                DateCreated = DateTimeOffset.Now,
                Name = model.SessionName
            });
        }

        return RedirectToAction(actionName: nameof(Index));
    }
}

テストランナーの実行には.NET SDK 3.0.100が必要
実行環境にSDKがインストールされていないと下記が表示される

Install the [3.0.100] .NET SDK or update [/Users/***/project/csharp/TestingControllersSample/tests/global.json] to match an installed SDK.

実行環境にインストールされているSDKをリストアップするコマンド

dotnet --list-sdks

SDKはこちらからダウンロードする

テストメソッド

IBrainstormSessionRepositoryのモックを生成

[Fact]
public async Task Index_ReturnsAViewResult_WithAListOfBrainstormSessions()
{
    // Arrange
    var mockRepo = new Mock<IBrainstormSessionRepository>();
    mockRepo.Setup(repo => repo.ListAsync())
        .ReturnsAsync(GetTestSessions());
    var controller = new HomeController(mockRepo.Object);

    // Act
    var result = await controller.Index();

    // Assert
    var viewResult = Assert.IsType<ViewResult>(result);
    var model = Assert.IsAssignableFrom<IEnumerable<StormSessionViewModel>>(
        viewResult.ViewData.Model);
    Assert.Equal(2, model.Count());
}

テスト実行

dotnet test

Test run for /Users/***/project/csharp/TestingControllersSample/tests/TestingControllersSample.Tests/bin/Debug/netcoreapp3.0/TestingControllersSample.Tests.dll(.NETCoreApp,Version=v3.0)
Microsoft (R) Test Execution Command Line Tool Version 16.3.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...

A total of 1 test files matched the specified pattern.

Test Run Successful.
Total tests: 16
     Passed: 16
 Total time: 2.6566 Seconds

Reference

ASP.NET Core でコントローラーのロジックの単体テストを行う
dotnet/AspNetCore.Docs
.NETダウンロード
Moq