代码之家  ›  专栏  ›  技术社区  ›  nerraga

为什么调用session.clear()会导致此测试失败?

  •  2
  • nerraga  · 技术社区  · 16 年前

    下面是一个针对FluentHibernate-1.1.0.685(NHibernate-2.1.2.4000)的存储库的简单测试。会话和NH配置由测试夹具提供。

    [Test] public void ShouldEdit() {
        var employee = CreateEmployee();
        session.Clear();
    
        var changedEmployee = _testRepository(employee.id);
        changedEmployee.FirstName = "Ringo";
        _testRepository.SaveOrUpdate(changedEmployee);
    
        session.Flush();
        session.Clear(); // Pulling this call will allow the test to pass.
    
        var employees = (IList)_testRepository.GetAll();
        Assert.Contains(changedEmployee, employees);
        Assert.IsFalse(employees.Contains(employee));
    }
    
    Employee CreateEmployee() {
        var e = {Id = 1, FirstName = "George", LastName = "Washington" };
        _testRepository.SaveOrUpdate(e);
        session.Flush();
        return e;
    }
    

    如果我去掉第二个调用clear(),这个测试将通过。但是,如果我退出呼叫,测试将失败,并出现以下情况:

    Failed:
    Expected: Collection containing <Employee>
    But was: < <Employee> >
    

    不是很有帮助。把它放在一边,为什么我需要删除第二个call to clear()?

    flush()将与数据库同步,如果我理解 documentation 正确地说,clear()将逐出会话缓存。这似乎正是我想要的行为,所以我可以确定我没有针对过时数据进行测试。事实上,我希望测试失败 没有 调用clear(),但事实并非如此。有人能解释一下这种行为吗?

    (注意:这是pragprog书“test drive asp.net mvc”第10章中存储库测试的一个变体。好书BTW.

    1 回复  |  直到 16 年前
        1
  •  7
  •   cbp    16 年前

    因为您的contains方法正在检查引用的相等性,而您可能希望使用ID或雇员的名称检查相等性。

    调用clear()将从nhibernate的会话中删除对changedemployee的引用(nhibernate将不再使用此引用)。这意味着重新加载员工时,将创建已更改员工的新实例。此引用不会通过对原始ChangedEmployee对象的引用相等性检查(尽管其所有属性都应相同)。

    如果不使用clear(),nhibernate将维护对changedEmployee对象的引用,并且getAll方法将返回相同的引用。

    推荐文章