NHibernate Load vs. Get行为用于测试

时间:2011-08-30 19:00:00

标签: unit-testing nhibernate

在简单的测试中,我可以通过它的Id是否不再是默认值来断言对象是否已被持久化。但是删除一个对象并想要检查该对象及其子对象是否不在数据库中,对象Id仍将保存其保存的值。

所以我需要转到db,我想要一个帮助器断言来使测试更具可读性,这就是问题的来源。我喜欢使用Load保存db调用的想法,但是我我想知道随后的例外是否会破坏会议。

我想,下面是两个断言的外观。你会用哪个?

干杯,
Berryl

获取

public static void AssertIsTransient<T>(this T instance, ISession session)
    where T : Entity
{
    if (instance.IsTransient()) return; 

    var found = session.Get<T>(instance.Id);
    if (found != null) Assert.Fail(string.Format("{0} has persistent id '{1}'", instance, instance.Id));
}

加载

public static void AssertIsTransient<T>(this T instance, ISession session)
    where T : Entity
{
    if (instance.IsTransient()) return; 

    try
    {
        var found = session.Load<T>(instance.Id);
        if (found != null) Assert.Fail(string.Format("{0} has persistent id '{1}'", instance, instance.Id));
    }
    catch (GenericADOException)
    {
        // nothing
    }
    catch (ObjectNotFoundException)
    {
        // nothing
    }
}

修改

在任何一种情况下,我都会在新会话中进行提取(获取或加载),而不是执行保存或删除的会话中的状态。

我正在尝试测试级联行为,而不是测试NHib删除内容的能力,但也许我在考虑这个或者有一种我没想过的更简单的方法。

1 个答案:

答案 0 :(得分:6)

“加载”部分中的代码将始终命中Assert.Fail,但永远不会抛出异常,因为Load<T>将返回代理(设置了Id属性 - 或从第1级缓存填充)没有击中DB - 即。如果您在已删除的实体上访问除Id属性之外的属性,则ISession.Load将失败。

关于你的“获取”部分 - 我可能会弄错,但我认为如果你在一个会话中删除一个实体 - 后来尝试在同一个会话中使用.Get - 你将获得一个级别的一个缓存 - 并且再次不返回null。

有关.Load和.Get。

的完整说明,请参阅此post

如果你真的需要查看它是否在你的数据库中 - 使用IStatelessSession - 或者启动一个子ISession(它将有一个空的一级缓存。

编辑:我想到了一个更大的问题 - 当提交事务时(默认情况下刷新会话时)将首先删除您的实体 - 所以除非您手动刷新会话(不推荐),否则您仍然可以使用它在你的数据库中。

希望这有帮助。

相关问题