当一个单元测试依赖于另一个单元测试并且由于NHiberante会话中的对象而失败时,我有一个奇怪的行为。
我得到'NHibernate.PropertyValueException:not-null属性引用null或者瞬态'只有当我从fixture运行所有单元测试时(为简单起见我只有两次测试)。如果我运行其中一个它总是通过。
我觉得我应该做一些清理工作。我尝试了session.Clean()和session.Evict(obj),但它没有帮助。有人可以解释一下这里发生了什么吗?
实体:
public class Order
{
public virtual Guid Id { get; protected set; }
public virtual string Name { get; set; }
}
映射(使用Loquacious API):
public class OrderMapping : ClassMapping<Order>
{
public OrderMapping()
{
Id(e => e.Id, m =>
{
m.Generator(Generators.Guid);
m.Column("OrderId");
});
Property(e => e.Name, m => m.NotNullable(true));
}
}
Fixture ctor(使用内存数据库):
var config = new Configuration();
config.CurrentSessionContext<ThreadStaticSessionContext>();
config.DataBaseIntegration(db =>
{
db.ConnectionString = "uri=file://:memory:,Version=3";
db.Dialect<SQLiteDialect>();
db.Driver<CsharpSqliteDriver>();
db.ConnectionReleaseMode = ConnectionReleaseMode.OnClose;
db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
db.LogSqlInConsole = true;
})
.SessionFactory()
.GenerateStatistics();
var mapper = new ModelMapper();
mapper.AddMappings(Assembly.GetExecutingAssembly().GetExportedTypes());
config.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities());
ISessionFactory sessionFactory = config.BuildSessionFactory();
this.session = sessionFactory.OpenSession();
// This will leave the connection open
new SchemaExport(config).Execute(
true, true, false, this.session.Connection, null);
CurrentSessionContext.Bind(this.session);
单元测试:
[Test]
[ExpectedException(typeof(PropertyValueException))]
public void Order_name_is_required()
{
var order = new Order();
this.session.Save(order);
}
[Test]
public void Order_was_updated()
{
var order = new Order { Name = "Name 1" };
this.session.Save(order);
this.session.Flush();
order.Name = "Name 2";
this.session.Update(order);
Assert.AreEqual(this.session.Get<Order>(order.Id).Name, "Name 2");
}
订单更新失败,出现'NHibernate.PropertyValueException:not-null属性引用null或transient'异常。事实上,如果写完后,任何其他单元测试都会失败。
编辑1 找到了解决方案。上次当我尝试清理我使用的会话时
[TestFixtureTearDown]
而不是
[TearDown]
public void TearDown()
{
this.session.Clear();
}
在每次测试运行之前,所有这些都已正确清理并允许使用相同的会话,并且不会重新创建内存数据库结构。 对不起,我犯了一个明显的错误。
答案 0 :(得分:0)
不要为多个测试重复使用相同的会话。
此外,根据NHibernate文档,如果从会话/事务内部生成了异常,则不保证会话处于一致状态,并且必须在不进一步使用的情况下进行处理。