私は現在、EntityFrameworkを介して作成したリポジトリの単体テストを試みています。
私がしたいのは、実際のデータベースに実際に送信/接続せずにリポジトリをテストすることです。モックフレームワークを使用せずにこれを実行したいと思います。
現在、私のテストはデータベースにデータを送信しています。これはテスト専用であるため、実際のデータをデータベースに送信せずに、追加/削除などのメソッドをテストすることです。
リポジトリは次のとおりです。
namespace AbstractFactory.Repository
{
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
/// <summary>
/// This class serves as the structure of the Author repository using a database
/// </summary>
public class DbAuthorRepository : IRepository<AuthorEntity>
{
private AbstractFactoryPatternEntities context;
public DbAuthorRepository(AbstractFactoryPatternEntities context)
{
this.context = context;
}
/// <summary>
/// Adds the specified author.
/// </summary>
/// <param name="author">The author.</param>
public void Add(AuthorEntity author)
{
context.AuthorEntities.Add(author);
}
/// <summary>
/// Removes the specified author.
/// </summary>
/// <param name="author">The author.</param>
public void Remove(AuthorEntity author)
{
this.context.AuthorEntities.Remove(author);
}
/// <summary>
/// Saves this instance.
/// </summary>
public void Save()
{
this.context.SaveChanges();
}
/// <summary>
/// Gets all.
/// </summary>
/// <returns>returns a list of all the authors</returns>
public IEnumerable<AuthorEntity> GetAll()
{
List<AuthorEntity> result = this.context.AuthorEntities.Include(a => a.Books).ToList();
return result;
}
/// <summary>
/// Gets the author by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns>returns an entity</returns>
public AuthorEntity GetById(int id)
{
AuthorEntity result = this.context.AuthorEntities.Single(a => a.AuthorId == id);
return result;
}
}
}
単体テストの現在のコードは次のとおりです。
[TestMethod]
public void Add_MethodIsCalled_EntityCountIsIncrementedByOne()
{
using (ShimsContext.Create())
{
ShimAbstractFactoryPatternEntities context = new ShimAbstractFactoryPatternEntities(new AbstractFactoryPatternEntities());
DbAuthorRepository repository = new DbAuthorRepository(context);
repository.Add(new AuthorEntity { FirstName = "Test", LastName = "testing=" });
var actual = repository.GetAll().Count();
repository.Save();
var expected = repository.GetAll().Count();
Assert.AreNotEqual(actual, expected);
}
//AbstractFactoryPatternEntities context = new AbstractFactoryPatternEntities();
//DbAuthorRepository repository = new DbAuthorRepository(context);
//var actual = repository.GetAll().Count();
//repository.Add(new AuthorEntity { FirstName = "Testing", LastName = "MyTest" });
//repository.Save();
//var expected = repository.GetAll().Count();
//Assert.AreNotEqual(actual, expected);
}
[TestMethod]
public void Remove_MethodIsCalled_EntityCountRemainsTheSame()
{
AbstractFactoryPatternEntities context = new AbstractFactoryPatternEntities();
DbAuthorRepository repository = new DbAuthorRepository(context);
AuthorEntity newAuthor = new AuthorEntity { FirstName = "Testing", LastName = "MyTest" };
repository.Add(newAuthor);
repository.Save();
var actual = repository.GetAll().Count();
Console.WriteLine(actual);
repository.Remove(newAuthor);
var expected = repository.GetAll().Count();
Console.WriteLine(expected);
Assert.AreEqual(actual, expected);
}
[TestMethod]
public void Get_MethodIsCalled_CorrectAuthorIsRetrieved()
{
AbstractFactoryPatternEntities context = new AbstractFactoryPatternEntities();
DbAuthorRepository repository = new DbAuthorRepository(context);
int target = 4;
AuthorEntity author = repository.GetById(target);
Assert.AreEqual(target, author.AuthorId);
}
テストを行うためにシム/スタブ/フェイクを使用したいと思います。
Entity Frameworkリポジトリは、リポジトリインターフェイスの具体的な実装です。具体的であるため、データベースなしで抽象化してテストすることはできません。この具体的な実装の要点は、データベースにデータを書き込むことです。
つまり、EFリポジトリのテストは、リポジトリが実際のデータベースに書き込むことを確認することを目的とする必要があります。テストの実行フェーズではリポジトリメソッドを呼び出し、アサートフェーズではデータベース(ado.net)からデータを取得する他の方法を使用します。おそらく?)リポジトリがその仕事をしているかどうかを確認します。
さらに別の無関係なことは、インメモリデータストアを使用するリポジトリの別の実装を作成でき、そのようなインメモリリポジトリを他のサービスに挿入すると、物理データベースに書き込むことなくこれらのサービスをテストできることです。動作テストを実行するためだけに、他のサービスに挿入されたリポジトリをモックすることもできます。つまり、サービスがリポジトリを正しく使用しているかどうかをテストします。
データベースへの接続を、EffortなどのインメモリDBに置き換えることができます。次に、リポジトリロジックをテストできます。詳細はこちらをご覧ください こちら