.Net Core XunitテストでのDBContext(EFのAsyncメソッド)のmock化

C#のdotnet coreでの単体テスト(Xunit)について。DBContextをmock化したい時の方法。普通ユニットテストにおいて実際のDBに対してReadWriteすることはないはずなので、綺麗にmock化したい。しかし、Xunitの純正のMockだとAsyncな処理がうまくMock化できなかったので、「MockQueryable」を使用する。

テスト対象のコード

まず対象のコード。サービスクラス内でEFのasync処理して何かを行うことを想定。

    public class UserService : IUserService
    {
        private AppDbContext _context;

        public UserService(AppDbContext context)
        {
            _context = context ?? throw new System.ArgumentNullException(nameof(context));
        }

        public async Task<User> GetUserHoge()
        {
            var users = await _context.User.ToListAsync();
            // 以下何かの処理
        }
    }

EF-asyncメソッドのmock

まず、「MockQueryable」をインストールする。
https://github.com/romantitov/MockQueryable

dotnet add package MockQueryable.Moq
var appDbContext = new Mock<AppDbContext>(null);
var users = new List<User>
{   // mockが返すデータを準備
    new User
    {
        Id = 1,
        Name = "Hoge"
    }
};
appDbContext.Setup(c => c.Role).Returns(users.AsQueryable().BuildMockDbSet().Object);
var service = new UserService(appDbContext.Object);
var result = service.GetUserHoge();

これでEFのAsyncメソッドも全般的にMock化することができる。純正がこのくらいシンプルにできればいいのだが。