永続化のためにCastle ActiveRecordを使用しています。次のことを行う永続化テストの基本クラスを作成しようとしています:
- テスト ケースごとにトランザクションを開き、テスト ケースの最後にロールバックして、テスト ケースごとにスキーマを再構築しなくても、テスト ケースごとにクリーンな DB を取得できるようにします。
- NHibernate セッションをフラッシュし、テストの途中で新しいセッションを取得する機能を提供して、永続化操作が NHibernate セッションだけでなく DB に実際にヒットしたことを確認できるようにします。
基本クラス ( ) が機能していることを証明するためにARTestBase
、次のサンプル テストを作成しました。
[TestFixture]
public class ARTestBaseTest : ARTestBase
{
[Test]
public void object_created_in_this_test_should_not_get_committed_to_db()
{
ActiveRecordMediator<Entity>.Save(new Entity {Name = "test"});
Assert.That(ActiveRecordMediator<Entity>.Count(), Is.EqualTo(1));
}
[Test]
public void object_created_in_previous_test_should_not_have_been_committed_to_db()
{
ActiveRecordMediator<Entity>.Save(new Entity {Name = "test"});
Assert.That(ActiveRecordMediator<Entity>.Count(), Is.EqualTo(1));
}
[Test]
public void calling_flush_should_make_nhibernate_retrieve_fresh_objects()
{
var savedEntity = new Entity {Name = "test"};
ActiveRecordMediator<Entity>.Save(savedEntity);
Flush();
// Could use FindOne, but then this test would fail if the transactions aren't being rolled back
foreach (var entity in ActiveRecordMediator<Entity>.FindAll())
{
Assert.That(entity, Is.Not.SameAs(savedEntity));
}
}
}
これが基本クラスでの私の最善の努力です。を正しく実装Flush()
しているため、3 番目のテスト ケースはパスします。ただし、トランザクションはロールバックされないため、2 番目のテストは失敗します。
public class ARTestBase
{
private SessionScope sessionScope;
private TransactionScope transactionScope;
[TestFixtureSetUp]
public void InitialiseAR()
{
ActiveRecordStarter.ResetInitializationFlag();
ActiveRecordStarter.Initialize(typeof (Entity).Assembly, ActiveRecordSectionHandler.Instance);
ActiveRecordStarter.CreateSchema();
}
[SetUp]
public virtual void SetUp()
{
transactionScope = new TransactionScope(OnDispose.Rollback);
sessionScope = new SessionScope();
}
[TearDown]
public virtual void TearDown()
{
sessionScope.Dispose();
transactionScope.Dispose();
}
protected void Flush()
{
sessionScope.Dispose();
sessionScope = new SessionScope();
}
[TestFixtureTearDown]
public virtual void TestFixtureTearDown()
{
SQLiteProvider.ExplicitlyDestroyConnection();
}
}
インメモリ データベースでカスタム SQLite プロバイダーを使用していることに注意してください。このブログ投稿から引用した私のカスタム プロバイダーは、スキーマを維持するために常に接続を開いたままにします。これを削除して通常の SQL Server データベースを使用しても、動作は変わりません。
必要な動作を実現する方法はありますか?