这并不是一个学习 TDD 的好问题。我假设您还不知道复杂的查询是什么样的,并且您想使用测试驱动技术来解决它。太棒了:)
但让我们看看我能不能回答你的问题。
是
任何包含真实数据库的测试,无论是内存中的还是磁盘上的,都不是单元测试。单元测试将使用模拟数据库。
也许 - 如果您的查询足够复杂,那么不会。
testGetUsersForPrinting 或 getUsersForPrintingTest 或类似
我很可能会在 SQL 解释器中驱动查询,而不是在代码中。目的是根据我在此过程中学到的知识,针对内存数据库生成一系列集成测试。
从您能想到的最小 DTO 开始,然后从那里开始构建。
最后将查询转换为 nhibernate 调用,然后使集成测试通过。
测试驱动,但不是真正的单元测试驱动。
如果您愿意接受最大程度的 TDD 纪律并处理比平时更慢和更烦人的工作,您可以在开发每个集成测试并编写代码以使其通过时自动化。这将意味着您在 3 个抽象级别/编辑器/环境(直接 SQL 查询、集成测试、c# 代码)之间频繁切换 - 我通过设置技术来强制自己每次都遵循正确的步骤来处理这个问题。
最后一点是为什么这不是学习 TDD 的好问题。您将需要很多您可能还没有强迫自己获得的纪律!
祝你好运。
好的,一些具体的例子。我会将您的代码示例修改为如下所示
public PrintDTO GetUsersForPrinting(int userId, ISession session)
{
var data = session.QueryOver<User>().//some joins, conditions etc.
return data; // or whatever
}
在你的单元测试中你会写
public testDTO()
{
//Arrange
StubSession session = .... setup a stub session, which returns hardcoded values
// Act
PrintDTO users = GetUsersForPrinting(111, session);
// Assert
Assert.That(users.size(), Is.EqualTo(1));
Assert.That(users.get(0).userId, Is.EqualTo(111));
}
在您的集成测试中,您将使用一个真实的数据库,并且您的会话对象将实际连接到它,并且将针对该数据库解析查询
Arrange-Act-Assert 是组织单元测试的标准方法。
通常,您希望在单元测试中尽可能少地使用断言。你将有多个单元测试。
在编写单元测试时,首先编写 Assert,然后填写其余部分以使其编译/获得所需的结果。首先让测试失败,因为这样你就知道当它通过时你确实交付了一些东西。
在这个实现存根 ISession 的示例中,您将从 ISession 派生一个本地 StubSession 类(仅对测试套件可见),只需填写绝对最小值以使其编译,并返回最小数据以进行测试通过。
要建立您的整个 DTO - 假设您知道自己想要在 DTO 中做什么 - 正如您在 cmets 中所说的那样,逐步进行。构建 DTO 的每个部分
一次一块,为每一块添加一个单元测试。
跟踪这是 TDD 规则的另一部分。
为自己设置一个 TODO 列表 - 只是一个简单的文本文件,或者在测试套件开始时可能有一个冗长的 cmets。列出您要测试的所有内容,例如0 个结果,1 个结果,2 个结果,20 个结果。用户 ID,您需要拥有的任何其他信息。
如果您正在跨表执行复杂查询,或者为每个连接添加待办事项,where 子句的每个部分等。
如果您正在使用这些项目,请添加用于订购和分页等的项目。
首先选择最简单的东西。一次只做一件小事(在一个红-绿-重构周期中)。在处理清单时,您可能希望将项目分解成更小的部分,或者您可能会想到需要做的其他事情。将它们添加到 TODO 列表中,而不是直接处理它们。
在这种特殊情况下,我会在每个 red-green-refactor 循环之后交换到 SQL 环境和/或 sqlite 集成测试,以找出如何使下一部分工作。我想这是介于红色和绿色之间的一种步骤——选择接下来要测试的内容,编写测试(显然失败了),在 SQL 中摆弄直到你知道如何让它通过,编写 nHibernate 调用来进行测试绿色,然后重构。
请注意,您列出的某些内容可能会用完而不必要,或者花费太长时间等。最好还是把它们写下来,这样您就可以知道哪些事情没有做以及您正在做的事情。专注于你的目标。
我还倾向于制定一个“气味”和/或重构列表,我可以看到我想做但还没有完全准备好这个周期。请记住尽量减少重复/重构您的测试以及您的 SUT(被测系统)。
这是一种做而不是看到的事情。您最终使用的单元测试列表以及它们执行的代码并不是对旅程的很好描述。 Kent Beck 的原始 TDD 书很薄,会给你一些很好的总体指导,但并不是真正关于构造查询。
这些有帮助吗?