したがって、いくつかの結論。私はこれを、誰かが/ユニットテストEF、ウィンザーとMVCを一緒に使ってみようとしている人のために書いていると思った。
まず、DbContextはRepositoryとUnit of Workの両方のパターンを実装しているため、これらの実装が役立つかどうか、独自に作成する必要があるかどうかを確認する必要があります。
DDDパターンに従って、自分のリポジトリを作成することを選択しました。集約ルートごとに1つです。その理由:クエリコードをカプセル化し、アプリケーション層に漏れないようにし、アプリケーションコントローラをテストするときに簡単に疑似できるようにすること。 IRepository<TEntity>
に基づいて汎用リポジトリを作成しました。そこにはたくさんの例があります。私はこれを良いものにしました:http://architects.dzone.com/articles/implementing-repository
一方、私はIUnitOfWorkサービスを削除し、代わりにデフォルトの実装を選択しました。しかし、私はIDbContext抽象化を作成しました(なぜマイクロソフトはこれを自分でやっていないのか分かりません)ので、リポジトリサービスをテストするときにDbContextを疑似できるようにしました。
私はIDbContextにリポジトリで使用したいDbContextのメンバーのみを与えました。だから、:
public interface IDbContext: IDisposable
{
Database Database { get; }
DbEntityEntry Entry(object entity);
IDbSet<TEntity> Set<TEntity>() where TEntity : class;
int SaveChanges();
}
私はその後、私のIDbContextとIRepositoryサービスのためのウィンザーの施設とインストーラを作成しました:
public class EntityFrameworkFacility: AbstractFacility
{
protected override void Init()
{
Kernel.Register(Component.For<IDbContext>()
.ImplementedBy<MyEntities>()
.LifestylePerWebRequest(),
Component.For(typeof(IRepository<>))
.ImplementedBy(typeof(Repository<>))
.LifestylePerWebRequest());
}
}
public class PersistenceInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.AddFacility<EntityFrameworkFacility>();
}
}
最後のピースはIDbContextを実装するためにEntity Frameworkのコンテキストクラスを拡張して、影になりましたセット(IDbSetではなくDbSet返すように)方法:位(ウィンザーのドキュメントに示されているControllerFactory登録)ですべてこれにより
public partial class MyEntities : IDbContext
{
public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
{
return base.Set<TEntity>();
}
}
を、それが必要に応じて、コントローラのコンストラクタにIRepositoryオブジェクト(またはIDbContext)を注入するウィンザーを得ることが自明になる:
リポジトリ単体テストで
public ControllerBase(IRepository<Contact> repo)
{
_repo = repo;
}
、実際のリポジトリインスタンスはモックIDbContextで裏打ちすることができる。
mocks = new MockRepository();
context = mocks.StrictMock<IDbContext>();
repo = new Repository<Contact>(context);
コントローラユニットテストでは、モックリポジトリを使用することができます
:
mocks = new MockRepository();
repo = mocks.StrictMock<IRepository<Contact>>();
ContactController controller = new ContactController(repo);
これをマークダウン誰に...あなたはなぜ言ってコメントを提供したいと思いますか?あなたがどこかでポイントを逃したと思うなら、理由を説明することで私を助けるかもしれません。 –
これは議論の質問であり、StackOverflow、特に最初のポイントには本当に適切ではないので、投票が中止されたと思います。 2つ目のポイントはCastle Windsorのサイトにあり、優れた文書があります。あなたの質問の内容を書いてください:単体テスト用のDbContextを嘲笑することは事実上不可能です(http://stackoverflow.com/a/13352779/861716)。私は、他のBLの純粋な単体テストプロジェクトの他に、DALテストのためにデータベースに対して「単体テスト」プロジェクトを使用します。カーストウィンザーは、インターフェースファクトリーからのインターフェース、インターフェースされていないインターフェース、インターフェース、バリデーターなどを注入します。 –
@GertArnoldに感謝します。模擬問題に関して、私はDALの単体テストを望んでいませんが、アプリケーションレイヤ(コントローラなど)にモックリポジトリを提供してテストすることができるようにするためです。城のドキュメントは一般的には良いですが、NHibernateの統合について扱っており、その領域ではかなりスケッチです。 –