单元测试数据库连接以及与数据库相关的代码和单元测试的一般问题

时间:2011-01-08 00:42:46

标签: java unit-testing testing

如果我有一个建立数据库连接的方法,那么如何测试这个方法呢?在连接成功的情况下返回bool是一种方式,但这是最好的方法吗?

从可测试性方法来看,最好将连接方法作为一种方法和方法来获取单独的方法吗?

另外,我如何测试从数据库中获取数据的方法?我可以对预期数据进行断言,但实际数据可能会发生变化,仍然是正确的结果集。

编辑:最后一点,检查数据,如果它应该是汽车列表,那么我可以检查它们是真正的汽车模型。或者如果它们是一堆Web服务器,我可以在系统上有一个存在的Web服务器列表,从测试中的代码返回,并获得测试结果。如果结果不同,数据是问题,但查询不是?

THnaks

5 个答案:

答案 0 :(得分:16)

首先,如果您涉及数据库,则不再进行单元测试。您已进入集成(用于连接配置)或功能测试域。那些是非常不同的野兽。

连接方法绝对应该与数据提取分开。实际上,您的连接应该来自工厂,以便您可以集中它。至于测试连接,实际上您可以通过建立与DB的连接来测试您的配置是否正确。您不应该尝试测试连接池,因为它应该是其他人编写的库(dbcp或c3p0)。此外,您可能无法对此进行测试,因为您的单元/集成/功能测试应该永远不会连接到生产级别数据库。

至于测试您的数据访问代码是否有效。这是功能测试,涉及很多框架和支持。您需要一个单独的测试DB,能够在测试期间动态创建模式,将任何静态数据插入表中,并在每次测试后将数据库返回到已知的干净状态。此外,应该实例化此DB,并以这样的方式运行,即2个人可以一次运行测试。特别是如果您有超过1个开发人员,还有一个自动化测试盒。

断言应该是针对静态数据(例如,状态列表,不经常更改)的数据,或者针对在测试期间插入的数据以及删除后的数据,因此它不会干扰其他测试。< / p>

编辑:如上所述,有一些框架可以帮助解决这个问题。 DBUnit相当常见。

答案 1 :(得分:2)

您可以从here获取创意。在单元测试数据库时我会去模拟对象。

否则,如果应用程序很大并且您正在运行冗长而复杂的单元测试,您还可以虚拟化数据库服务器并轻松将其还原为已保存的快照,以便在已知环境中再次运行测试。

答案 2 :(得分:1)

使用我的Acolyte框架(https://github.com/cchantep/acolyte),您可以模仿任何支持JDBC的DB,描述案例(如何处理每个执行的查询/更新)以及在每种情况下返回的结果集/ updatecount(将fixtures描述为行列表查询,计算更新)。

此类连接可以直接用于传递需要JDBC的实例,或者在JDBC URL命名空间jdbc:acolyte:中使用唯一ID注册,以便通过JDBC URL解析获得连接的代码。

无论创建连接的方式如何,Acolyte都会保持每个人的隔离,这对于单元测试是正确的(无需在测试数据库上进行额外的清理)。

由于持久性案例可以调度到不同的隔离连接,因此您不再需要一个难以管理的大型数据库(或数据夹具文件):它可以轻松地在各种连接中拆分,例如:每个持久性方法/模块一个。

我的Acolyte框架可以在纯Java或Scala中使用。

答案 3 :(得分:0)

如果目标是测试方法功能,而不是数据库SP或SQL语句,那么您可能需要考虑数据提供者接口意义上的依赖注入。换句话说,您的类使用带有返回数据的方法的接口。默认实现使用数据库。单元测试实现有几个选项:

  • 嘲笑(NMock,Moq等),很棒的方式,我活着嘲笑。
  • 内存数据库
  • 带有静态数据的静态数据库

我首先不喜欢任何东西。作为一般规则,对接口的编程总是更加灵活。

答案 4 :(得分:0)

对于数据库连接建立测试:您可以让连接执行一个非常简单的SQL作为测试方法。某些应用程序服务器具有此类配置,以下代码段来自JBoss DB配置:

<!--  sql to call on an existing pooled connection when it is obtained from pool 
<check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>