进行单元测试时,在测试CRUD操作时是否必须使用数据库? sql lite可以帮忙吗?你是否必须以某种方式在内存中创建数据库?
我正在使用mbunit。
答案 0 :(得分:12)
没有。集成实际数据库将是集成测试。不是单元测试。
是的,你可以使用任何内存数据库,如 SQLite 或 MS SQL Compact ,如果你不能在任何其他地方抽象(模拟)你的DAL / DAO方式。
考虑到这一点,我必须指出,单元测试可以一直到DAL,但不是DAL本身。 DAL必须在集成测试中使用某种实际DB进行测试。
答案 1 :(得分:12)
与所有复杂问题一样,答案是:它取决于:)
通常,您应该在接口后面隐藏数据访问层,这样您就可以在不使用数据库的情况下测试应用程序的其余部分,但是如果您想测试数据访问实现本身呢?
在某些情况下,有些人认为这是多余的,因为他们大多使用ORM等声明性数据访问技术。
在其他情况下,数据访问组件本身可能包含您可能要测试的一些逻辑。这可能是一个完全相关的事情,但你需要数据库才能做到这一点。
有些人认为这是集成测试而不是单元测试,但在我的书中,你所谓的并不重要 - 最重要的是你从全自动测试中获得价值,并且你绝对可以使用单元测试框架来推动这些测试。
前段时间我写了how to do this on SQL Server。要记住的最重要的事情是避免使用某些“代表性数据”创建通用夹具的诱惑,并尝试在所有测试中重复使用它。相反,您应该在每个测试中填写数据并在之后进行清理。
答案 2 :(得分:2)
进行单元测试时,在测试CRUD操作时是否必须使用数据库?
假设您已经提取了所述CRUD操作的接口,并通过模拟或存根测试了使用所述接口的所有内容。现在剩下一大堆代码,这是一个包含一些代码来绑定对象和一些SQL的保存方法。
如果是这样,那么我会声明一个“单位”并说你确实需要一个数据库,理想情况下,它至少是一个数据库的良好代表,以免你被特定于供应商的SQL所困扰。
我也会轻易使用模拟来强制错误条件,但我不会只用模拟来测试save方法本身。因此,从技术上讲,这可能是一个集成测试,我仍然会将其作为单元测试的一部分。
修改:错过了2/3的问题。遗憾。
sql lite可以帮忙吗?
我过去曾在内存数据库中使用过,因为我使用的数据库和实时系统做了不同的事情,或者他们花了很长时间才启动。我建议每个开发人员都有一个开发人员本地数据库。
你是否必须以某种方式在内存中创建数据库?
在数据库中是的。我使用DbUnit来分散数据并使用SQL脚本手动保持模式最新,但您可以只使用SQL脚本。拥有开发人员本地数据库会添加一些额外的维护,因为您同时拥有模式和数据集以跟上数据,但我个人觉得这是值得的,因为您可以确保数据库层按预期工作。
答案 3 :(得分:2)
正如其他人已经指出的那样,您要实现的不是单元测试,而是集成测试。
说到这一点,即使我更喜欢与模拟隔离的单元测试,集成测试也没有什么问题。因此,如果您认为在您的上下文中有意义,只需在您的测试策略中包含集成测试。
现在,关于你的问题,我会查看DbUnit.NET。我不知道这个工具的.NET版本,但我可以告诉你,Java版本非常适合与数据库交互的测试。简而言之,DbUnit允许您在运行测试之前将数据库置于已知状态,并对表的内容执行断言。真的很方便。顺便说一句,我建议您阅读Best Practices页面,即使您决定不使用此工具。
答案 4 :(得分:0)
实际上,如果您正在编写连接到数据库的测试,那么您正在进行集成测试,而非单元测试。
对于此类操作的单元测试,请考虑使用某些类型的mock-database对象。例如,如果您有一个封装数据库交互的类,则从中提取一个接口,然后创建一个继承类,该类使用简单的内存中对象,而不是实际连接到数据库。
答案 5 :(得分:0)
如上所述,此处的关键是在运行测试之前让测试数据库处于已知状态。在一个真实的例子中,我有几个在测试之前运行的SQL脚本,它们重新创建一组已知的测试数据。由此,我可以测试CRUD操作并验证是否插入/更新/删除了新行。
答案 6 :(得分:0)
我编写了一个名为DBSnapshot的实用程序来帮助集成测试 sqlserver数据库。
如果您的数据库架构经常更改,那么针对真实的数据库实例实际测试您的代码会很有帮助。人们使用SqlLite进行快速测试(因为数据库在内存中运行),但是如果要验证代码是否与数据库的实际构建有效,则这没有用。
在测试数据库时,您希望遵循以下模式:备份数据库,设置数据库以进行测试,运行代码,验证结果,将数据库还原到起始状态。
以上将确保您可以单独运行每个测试。如果您编写.net,我的DBSnapshot实用程序将简化您的代码。我认为它比DbUnit.NET更容易使用。