以下是针对 FluentNHibernate-1.1.0.685 (NHibernate-2.1.2.4000) 的存储库的简单测试。 Session 和 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> >
帮助不大。撇开这个不谈,为什么我需要删除对 Clear() 的第二次调用?
Flush() 将与数据库同步,如果我理解 documentation如果正确,Clear() 将清除 session 缓存。这似乎正是我想要的行为,因此我可以确定我不是在针对陈旧数据进行测试。事实上,如果没有调用 Clear(),我希望测试会失败,但事实并非如此。有人可以阐明这种行为吗?
(注意:这是在 PragProg 书“Test Drive ASP.Net MVC”的第 10 章中找到的存储库测试的变体。顺便说一句,好书。)
最佳答案
因为您的 Contains 方法正在检查引用是否相等,而您可能想使用 Id 或员工姓名来检查是否相等。
调用 Clear() 将从 NHibernate 的 session 中删除对 changedEmployee 的引用(NHibernate 将不再使用该引用)。这意味着当您重新加载员工时,将创建已更改员工的新实例。此引用不会通过与原始 changedEmployee 对象的引用相等性检查(尽管它的所有属性应该相同)。
在没有 Clear() 的情况下,NHibernate 维护对已更改的 Employee 对象的引用,并且该引用由 GetAll 方法返回。
关于c# - 为什么调用 Session.Clear() 会导致此测试失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3277876/