以下是针对 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() 将与数据库同步,如果我理解 文档正确,Clear() 将逐出会话缓存。这似乎正是我想要的行为,这样我就可以确定我没有针对过时的数据进行测试。事实上,我希望如果不调用 Clear(),测试就会失败,但事实并非如此。有人可以阐明这种行为吗?
(注意:这是 PragProg 书籍“Test Drive ASP.Net MVC”第 10 章中存储库测试的变体。顺便说一句,是一本好书。)
The following is a simple test of a repository against FluentNHibernate-1.1.0.685 (NHibernate-2.1.2.4000). The Session and NH config are provided by the test fixture.
[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;
}
This test will pass if I get rid of the second call to Clear(). If I leave the call in however then the test will fail with the following:
Failed:
Expected: Collection containing <Employee>
But was: < <Employee> >
Not very helpful. Leaving that aside, why do I need to remove the second call to Clear()?
Flush() will sync with the db and, if I understand the documentation correctly, Clear() will evict the session cache. This seems to be exactly the behavior I want so that I can be sure I'm not testing against stale data. In fact I would expect the test to fail without the call to Clear() and yet this isn't the case. Can someone shed some light on this behavior?
(Note: This is a variation on a repository test found in Chapter 10 of the PragProg book "Test Drive ASP.Net MVC". Good book btw.)
发布评论
评论(1)
因为您的 Contains 方法正在检查引用是否相等,而您可能希望使用 Id 或员工姓名检查是否相等。
调用Clear()将从NHibernate的会话中删除对changedEmployee的引用(NHibernate将不再使用这个引用)。这意味着当您重新加载员工时,会创建已更改员工的新实例。此引用不会通过与原始changedEmployee对象的引用相等性检查(尽管它的所有属性应该相同)。
如果没有 Clear(),NHibernate 会维护对changedEmployee 对象的引用,并且 GetAll 方法会返回相同的引用。
Because your Contains method is checking for reference equality, whereas you probably want to check for equality using the Id or employee's name.
Calling Clear() will remove the reference to changedEmployee from NHibernate's Session (NHibernate won't use this reference any more). This means when you reload the employees, a new instance of the changed employee is created. This reference won't pass a reference equality check with the original changedEmployee object (although all its properties should be the same).
Without the Clear(), NHibernate maintains a reference to the changedEmployee object and this same reference is returned by the GetAll method.