2

我有一段看起来像这样的代码:

public void Foo(int userId)
{
    try {
        using (var tran = NHibernateSession.Current.BeginTransaction())
        {
            var user = _userRepository.Get(userId);
            user.Address = "some new fake user address";
            _userRepository.Save(user);
            Validate();
            tran.Commit();
        }
    }
    catch (Exception) {
        logger.Error("log error and don't throw")
    }
}

private void Validate()
{
    throw new Exception();
}

我想对验证是否正确进行单元测试。我使用 nunit 和 SQLLite 数据库进行测试。这是测试代码:

protected override void When()
{
    base.When();
    ownerOfFooMethod.Foo(1);
    Session.Flush();
    Session.Clear();
}

[Test]
public void FooTest()
{
    var fakeUser = userRepository.GetUserById(1);
    fakeUser.Address.ShouldNotEqual("some new fake user address");
}

我的测试失败了。
在调试时,我可以看到抛出了异常,但尚未调用 Commit。但是我的用户在地址属性中仍然有“一些新的假用户地址”,尽管我期待它会被回滚。
当我查看 nhibernate profiler 时,我可以看到 begin transaction 语句,但它后面既没有提交也没有回滚。
更重要的是,即使我将 try-catch 块放在那里并在 catch 中显式执行 Rollback,我的测试仍然失败。
我认为测试环境存在一些问题,但对我来说一切似乎都很好。

有任何想法吗?

编辑:我添加了重要的 try-catch 块(一开始我已经简化了太多代码)。

4

1 回答 1

3

如果在 NH 将更改刷新到数据库之前发生异常,并且如果您继续使用该会话而不驱逐/清除对象并且由于某种原因稍后发生刷新,则更改仍将保持不变,因为对象仍然是脏的根据NHibernate。回滚事务时,您应该立即关闭会话以避免此类问题。

另一种说法:回滚不会回滚您对持久实体所做的内存更改。

此外,如果会话是常规会话,则不需要调用 Save(),因为该实例已由 NH 跟踪。

于 2012-11-14T15:30:06.513 回答