Instanciate
メソッドをオーバーライドし、次のことを行う NHibernate インターセプターがあります。
- インスタンス化されるクラスが特定の基本クラスを継承する場合、CastleDynamicProxy を返します
- それ以外の場合は、クラスをインスタンス化するだけです
これはかなり簡単に聞こえますが (そして既に機能しています)、単体テストでその機能を証明できれば、さらに気分が良くなります。
インターセプターのコードは次のとおりです。
public override object Instantiate(string entityTypeName, EntityMode entityMode, object id)
{
// Type resolution across Assembly borders
Type type = TypeFinder.FindType(entityTypeName);
if (type == null)
{
throw new Exception(string.Format("",entityTypeName));
}
bool isViewModel = (typeof(ViewModelBase).IsAssignableFrom(type));
if (entityMode == EntityMode.Poco && isViewModel)
{
var instance = ProxyFactory.CreateProxy(type);
SessionFactory.GetClassMetadata(entityTypeName).SetIdentifier(instance, id, entityMode);
return instance;
}
return base.Instantiate(entityTypeName, entityMode, id);
}
プロキシ生成コードを正常にテストできますが、base.Instantiate
常に null が返されます。これが私のテスト コードです (ご覧のとおり、Interceptor が有効なセッションを必要とする場合に備えて、実際のデータベースも追加しました)。
private FluentConfiguration PrepareDataBase()
{
string connectionString = @"Data Source=test.sdf;";
SqlCeEngine en = new SqlCeEngine(connectionString);
en.CreateDatabase();
FluentConfiguration fc = Fluently.Configure().Database(MsSqlCeConfiguration.Standard
.ConnectionString(c => c.Is(connectionString))
.ShowSql())
.Mappings(x => x.FluentMappings.AddFromAssemblyOf<ViewModel>());
new SchemaExport(fc.BuildConfiguration()).Create(true, true);
return fc;
}
[TestMethod]
[DeploymentItem("System.Data.SqlServerCe.dll")]
public void Test_Instantiate_WithNonViewModelBasedPoco_ReturnsInstance()
{
TypeFinder.RegisterAssembly(typeof(OtherPoco).Assembly);
FluentConfiguration fc = PrepareDataBase();
NhChangeNotificationInterceptor interceptor = new NhChangeNotificationInterceptor();
ISession session = fc.BuildSessionFactory().OpenSession(interceptor);
string instanceType = typeof(OtherPoco).FullName;
object instance = interceptor.Instantiate(instanceType, EntityMode.Poco, null);
Assert.AreEqual(typeof(OtherPoco).FullName, instance.GetType().FullName);
Assert.IsFalse(typeof(ViewModelBase).IsAssignableFrom(instance.GetType()));
}
null 識別子に問題があるのではないかと考えたので、レコードを保存し、その Id を次のように追加しようとしました。
NhChangeNotificationInterceptor interceptor = new NhChangeNotificationInterceptor();
ISession session = fc.BuildSessionFactory().OpenSession(interceptor);
using (ITransaction trx = session.BeginTransaction())
{
session.Save(new OtherPoco() { Id = 1 });
session.Flush();
}
string instanceType = typeof(OtherPoco).FullName;
object instance = interceptor.Instantiate(instanceType, EntityMode.Poco, 1);
といっても、何も変わりません。どのようにテストできますbase.Instantiate
か?