gpt4 book ai didi

unit-testing - SQLite 单元测试 NHibernate 生成级联关系

转载 作者:行者123 更新时间:2023-12-03 12:33:10 25 4
gpt4 key购买 nike

以下是这篇文章的一些背景信息。如果您愿意,可以直接跳到问题:

在这篇优秀的文章 (http://ayende.com/Blog/archive/2009/04/28/nhibernate-unit-testing.aspx) 中,作者认为“在使用 NHibernate 时,我们通常只想测试三件事:
1) 属性被持久化,
2)级联按预期工作
3) 查询返回正确的结果。
-) 映射是完整和正确的(暗示)

我的看法是,他继续说 SQLite 可以而且应该成为完成上述所有工作的首选单元测试工具。应该指出的是,作者似乎是那里更有经验和技能的 NHib 开发人员之一,尽管他在文章中没有明确表示,但他在稍后的问题中暗示该域可以而且应该处理一些SQLite 的缺点。

题:

您如何使用 SQLite 来测试级联关系,尤其是在它不检查外键约束的情况下。您如何测试模型以确保外键约束不是数据库问题。

以下是我为测试级联行为而提出的一些单元测试。该模型只是一个可以有零到多个 StaffMembers 的部门,级联设置为 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,因为后者不检查外键约束。

这是关系另一方的测试;一个 StaffMember 可以有一个部门,级联设置为 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 测试吗?这些测试值得吗?

干杯,
贝瑞尔

最佳答案

据我了解,这篇文章是关于测试 NHibernate 映射的。在我看来,这与 db 相关问题无关,而是与测试您在映射中设置的 nhibernate 属性有关。无需断言不可能创建无效数据:您只需证明您的代码创建了所需的结果和/或检查您想要检查的内容。您可以测试级联、级联删除和删除孤立。无论您在使用 sqlite 的测试中想要的方式如何。但是第三个测试试图测试约束,这不是 nhibernate 担心的。

如果你想测试你的数据库约束,你确实应该使用你的生产数据库而不是 sqlite。您可以使用或不使用休眠来实现,但这与您的映射无关。
另一方面,如果您真的想要使用 SQLite 进行外键测试的解决方法,您可以尝试使用此 foreign_key_trigger_generator .我还没有尝试过,但它似乎会生成插入前触发器,以确保引用的 Pk 的存在。
也许你可以写一个评论这个工具是否有用。

关于unit-testing - SQLite 单元测试 NHibernate 生成级联关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1227924/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com