我有一個NHibernate的攔截器,它覆蓋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。 這裏是我的測試代碼(正如你看到的,我甚至增加了一個真正的數據庫,公正的情況下攔截器需要一個有效的會話):
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()));
}
我想這可能是與空標識的問題,所以我保存了記錄,並試圖增加其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
?
是'base.Instantiate'你的代碼?如果沒有,那麼我在單元測試中看不到什麼價值。如果你想要100%的代碼覆蓋率,那麼你可以將'base.Instantiate'調用包裝成一個你可以聲稱被調用的虛擬方法。 – wal 2013-02-25 14:05:41
base.Instantiate不是我的代碼。感謝您指出了這一點。 – 2013-02-25 14:11:02