4
私はMoqが新しく、データのバッキングストアのように使用したいが、ライブデータベースには触れない。次のようにEntity FrameworkとMoqを使用してユニットテストを行うにはどうすればよいですか?
私のセットアップは次のとおりです。
- AのUnitOfWorkは、すべてのリポジトリが含まれており、アプリケーション全体のデータアクセスのために使用されています。
- リポジトリは、DbContextによって提供されるDbSetへの直接フックを表します。
- DbContextにはすべてのDbSetsが含まれています。ここで
は、これまでのところ、私のテストです:それは、ユーザーがモックDbSetに追加されたことを確認することができますよう
// ARRANGE
var user = new User()
{
FirstName = "Some",
LastName = "Guy",
EmailAddress = "[email protected]",
};
var mockSet = new MockDbSet<User>();
var mockContext = new Mock<WebAPIDbContext>();
mockContext.Setup(c => c.Set<User>()).Returns(mockSet.Object);
// ACT
using (var uow = UnitOfWork.Create(mockContext.Object))
{
uow.UserRepository.Add(user);
uow.SaveChanges();
}
// ASSERT
mockSet.Verify(u => u.Add(It.IsAny<User>()), Times.Once());
私のテストは、成功のようだ - しかし、私は何をする必要があるが、実際に取得することですそのデータを元に戻し、さらにアサーションを実行します(単なるアドホックテストです)。
フレームワークのテストが私の頭の中で行われていることをアドバイスしてください。また、使いやすくすれば他のテストフレームワークに移行することもできます。
ありがとうございます。
更新:ここに私の作業コードがあります。
ユニットテスト
// ARRANGE
var user = new User()
{
FirstName = "Some",
LastName = "Guy",
EmailAddress = "[email protected]",
};
var mockSet = new MockDbSet<User>();
var mockContext = new Mock<WebAPIDbContext>();
mockContext.Setup(c => c.Set<User>()).Returns(mockSet.Object);
// ACT
using (var uow = UnitOfWork.Create(mockContext.Object))
{
uow.UserRepository.Add(user);
uow.SaveChanges();
}
// ASSERT
mockSet.Verify(u => u.Add(It.IsAny<User>()), Times.Once());
// TODO: Further assertations can now take place by accessing mockSet.BackingStore.
}
MockDbSet
class MockDbSet<TEntity> : Mock<DbSet<TEntity>> where TEntity : class
{
public ICollection<TEntity> BackingStore { get; set; }
public MockDbSet()
{
var queryable = (this.BackingStore ?? (this.BackingStore = new List<TEntity>())).AsQueryable();
this.As<IQueryable<TEntity>>().Setup(e => e.Provider).Returns(queryable.Provider);
this.As<IQueryable<TEntity>>().Setup(e => e.Expression).Returns(queryable.Expression);
this.As<IQueryable<TEntity>>().Setup(e => e.ElementType).Returns(queryable.ElementType);
this.As<IQueryable<TEntity>>().Setup(e => e.GetEnumerator()).Returns(() => queryable.GetEnumerator());
// Mock the insertion of entities
this.Setup(e => e.Add(It.IsAny<TEntity>())).Returns((TEntity entity) =>
{
this.BackingStore.Add(entity);
return entity;
});
// TODO: Other DbSet members can be mocked, such as Remove().
}
}
模擬データベースセットのコードを表示します。バッキングストアとして機能するコレクションを作成し、列挙型dbセットをバッキングコレクションでモックするだけで済みます。 – Nkosi
申し訳ありません。私は自分の投稿を更新しました。 MockDbSetはテストされていません。なぜなら、どのようにして一緒に収まるかわからないからです。私は "クエリ可能な"変数がDbSetのためにそのように動作することを疑うだろう。 模擬DbSetにフックすることでバッキングストアとして機能するコレクションを作成するにはどうすればよいですか? – Rhonage