以下是關於這篇文章的一些背景信息。您可以直接跳過,如果你喜歡這樣的問題:筆者認爲,「當使用NHibernate我們一般只需要測試三件事SQLite單元測試NHibernate生成級聯關係
在這個優秀的文章(http://ayende.com/Blog/archive/2009/04/28/nhibernate-unit-testing.aspx):
1)屬性依然存在,
2)級聯按預期工作 3)查詢返回正確的結果 - ),其映射完成&正確的(隱含的)
我的看法是,他接着說,SQLite的可以而且應該是單位測試工具的選擇做以上所有的事情。應該指出,作者似乎是更多的經驗之一有經驗的和熟練的NHib開發人員,儘管他在文章中沒有明確地說出這一點,但他後來在後面提出一個問題,即域可以並且應該處理SQLite的一些缺點。
問題:
你怎麼使用SQLite測試級聯關係,特別是考慮到它不檢查外鍵約束。如何測試模型以確保外鍵約束不會成爲數據庫問題。
這裏是一些單元測試,我想出了測試級聯行爲。該模型只是一個部門,可以有零到許多職員,級聯設置爲NONE。
[Test]
public void CascadeSaveIsNone_NewDepartmentWithFetchedStaff_CanSaveDepartment()
{
_newDept.AddStaff(_fetchedStaff);
Assert.That(_newDept.IsTransient(), Is.True);
_reposDept.SaveOrUpdate(_newDept);
_reposDept.DbContext.CommitChanges();
Assert.That(_newDept.IsTransient(), Is.False);
}
[Test]
public void CascadeSaveIsNone_NewDepartmentWithFetchedStaff_CannotSaveNewStaff()
{
_newDept.AddStaff(_newStaff);
Assert.That(_newDept.IsTransient(), Is.True);
Assert.That(_newStaff.IsTransient(), Is.True);
_reposDept.SaveOrUpdate(_newDept);
_reposDept.DbContext.CommitChanges();
Assert.That(_newDept.IsTransient(), Is.False);
Assert.That(_newStaff.IsTransient(), Is.True);
}
[Test]
public void CascadeDeleteIsNone_FetchedDepartmentWithFetchedStaff_Error()
{
_fetchedDept.AddStaff(_fetchedStaff);
_reposDept.SaveOrUpdate(_fetchedDept);
_reposStaff.DbContext.CommitChanges();
_reposDept.Delete(_fetchedDept);
var ex = Assert.Throws<GenericADOException>(() => _reposDept.DbContext.CommitChanges());
Console.WriteLine(ex.Message);
Assert.That(ex.Message, Text.Contains("could not delete:"));
Console.WriteLine(ex.InnerException.Message);
Assert.That(ex.InnerException.Message, Text.Contains("The DELETE statement conflicted with the REFERENCE constraint"));
}
[Test]
public void Nullable_NewDepartmentWithNoStaff_CanSaveDepartment()
{
Assert.That(_newDept.Staff.Count(), Is.EqualTo(0));
var fetched = _reposDept.SaveOrUpdate(_newDept);
Assert.That(fetched.IsTransient(), Is.EqualTo(false));
Assert.That(fetched.Staff.Count(), Is.EqualTo(0));
}
第三次試驗,「.._ FetchedDepartmentWithFetchedStaff_Error」的作品對SQL Server,但不是SQLite的,因爲後者不檢查外鍵約束。
這裏是測試關係的另一方;職員可以有一個部門,級聯設置爲NONE。
[Test]
public void CascadeSaveIsNone_NewStaffWithFetchedDepartment_CanSaveStaff()
{
_newStaff.Department = _fetchedDept;
_reposStaff.SaveOrUpdate(_newStaff);
_reposStaff.DbContext.CommitChanges();
Assert.That(_newStaff.Id, Is.GreaterThan(0));
}
[Test]
public void CascadeSaveIsNone_NewStaffWithNewDepartment_Error()
{
_newStaff.Department = _newDept;
Assert.That(_newStaff.IsTransient(), Is.True);
var ex = Assert.Throws<PropertyValueException>(() => _reposStaff.SaveOrUpdate(_newStaff));
Console.WriteLine(ex.Message);
Assert.That(ex.Message, Text.Contains("not-null property references a null or transient value"));
}
[Test]
public void CascadeDeleteIsNone_FetchedStaffWithFetchedDepartment_DeletesTheStaff_DoesNotDeleteTheDepartment()
{
_newStaff.Department = _fetchedDept;
_reposStaff.SaveOrUpdate(_newStaff);
_reposStaff.DbContext.CommitChanges();
_reposStaff.Delete(_newStaff);
Assert.That(_reposStaff.Get(_newStaff.Id), Is.Null);
Assert.That(_reposDept.Get(_fetchedDept.Id), Is.EqualTo(_fetchedDept));
}
[Test]
public void NotNullable_NewStaffWithUnknownDepartment_Error()
{
var noDept = new Department("no department");
_newStaff.Department = noDept;
var ex = Assert.Throws<PropertyValueException>(() => _reposStaff.SaveOrUpdate(_newStaff));
Console.WriteLine(ex.Message);
Assert.That(ex.Message, Text.Contains("not-null property references a null or transient"));
}
[Test]
public void NotNullable_NewStaffWithNullDepartment_Error()
{
var noDept = new Department("no department");
_newStaff.Department = noDept;
var ex = Assert.Throws<PropertyValueException>(() => _reposStaff.SaveOrUpdate(_newStaff));
Console.WriteLine(ex.Message);
Assert.That(ex.Message, Text.Contains("not-null property references a null or transient"));
}
這些測試成功針對Sql Server和SQLite。我可以信任SQLite測試嗎?這些有價值的測試?
乾杯,
Berryl