NHibernate.PropertyValueException:非空属性引用空或瞬态和依赖的单元测试

本文关键字:依赖 单元测试 引用 PropertyValueException 属性 NHibernate | 更新日期: 2023-09-27 18:01:45

我有一个奇怪的行为,当一个单元测试变得依赖于另一个,失败,因为在nhibernate会话对象。

我正在获取NHibernate。PropertyValueException:非空属性仅在从fixture运行所有单元测试(为了简单起见,我只有两个测试)时引用null或transient'。如果我运行其中一个,它总会通过。

我觉得我应该做一些清理工作。我尝试了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变量(使用内存中的数据库):

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");
}

Order was updated failed with 'NHibernate。PropertyValueException: not-null属性引用null或瞬态异常。实际上,任何其他单元测试都将失败,如果在。

编辑1 找到解决办法了。上次尝试清理会话时,我使用了

[TestFixtureTearDown]

代替

[TearDown]
public void TearDown()
{
    this.session.Clear();
}

每个测试运行之前正确地进行了所有清理,并允许使用相同的会话,并且不重新创建内存中的数据库结构。对不起,我犯了一个明显的错误。

NHibernate.PropertyValueException:非空属性引用空或瞬态和依赖的单元测试

不要在多个测试中重用相同的会话。

同样,根据NHibernate文档,如果一个异常已经从会话/事务内部生成,会话不能保证处于一致状态,必须处理,不再使用