2010-02-09 67 views
1

我想问你有关与数据库中的数据相关的写入测试。在我看来,最好的方法是使用不同的数据库模式,仅在单元测试时使用正确的数据。在测试代​​码中,我可以在ID的基础上加载对象。测试方法 - 数据库,Junit

第二一种可能是在单元测试过程中将数据放入数据库。我不喜欢它。

你怎么想。你怎么做到这一点?

亲切的问候 塞巴斯蒂安

回答

2

如果你真的想编写与数据库交互的测试 - 集成测试 - 那么你必须把你的数据库中已知的状态每次测试执行之前。要做到这一点

一种方法是使用DbUnit每次测试之前加载自定义数据集,例如。在这里,每个测试都负责他自己的数据,不需要清理,并且可以在测试失败后查询数据库以了解问题。

另一种方法是使用一个“活”的数据库,并运行一个事务内部测试,并回滚在测试结束的变化。 Spring和Unitils对此有支持。这很有效,但使用这种方法诊断失败的测试并不总是很容易。

需要注意的是第二种方法并没有真正排除第一个,你可以使用自定义的数据集在事务内。另外请注意,您可以使用包含“参考数据”(即只读数据,如国家等)的数据库,并且只使用“动态数据”来加快使用第一种方法时的速度。

就个人而言,我并不真正看到前一种方法有什么问题(除了可能测试速度稍慢),像DbUnit这样的工具使它变得非常容易。正如我所说的,我发现使用DbUnit进行测试更容易诊断。但后面的方法肯定也起作用。

在这两种情况下,你当然应该使用专用模式。

实际上,每个开发人员使用一个模式肯定是best practice

+0

太棒了!非常感谢你。 – Sebastian 2010-02-10 06:44:28

+0

帕斯卡尔,很好的详细答案。你在那里提到它,但我认为强调与活动数据库交互的测试通常是集成测试是很重要的。使用一个实时数据库进行单元测试会是过分的,嘲笑它是合适的。 – 2010-02-10 13:06:50

0

单元测试,你应该嘲笑或存根数据库的功能。由于您正在测试调用数据库的对象而不是数据库本身,因此不需要使用真实的数据库。 EasyMock或JMock是很好的嘲讽库来研究。

+0

谢谢。如果我有一个大对象图怎么办?然后,我需要编写大量代码来模拟对其他对象的每个引用。 Im在服务层使用模拟来模拟DAO层,因为DAO层已经过测试。而且,我还在GUI层中使用模拟来模拟服务层,因为服务层已经过测试。 你不觉得模拟数据库来测试DAO层不是一个好主意吗?我们想测试它,但在这种情况下,我们将测试模拟对象。你怎么看?谢谢你的回答。 – Sebastian 2010-02-09 13:58:45

+0

如果模拟的对象太多,这可能意味着你的设计太复杂了,而一个课也许有太多的责任。没有看到实际的代码,很难说,但看看你能否简化一下。 至于数据库,如果您正在模拟数据库,那么如果您的测试是针对DAO的,则不会测试模拟对象。您正在测试DAO将正确的命令发送到数据库。对于DAO测试,假设数据库将按预期运行是安全的(并且您可以随时嘲笑它以执行意想不到的事情来测试错误情况)。 – 2010-02-09 14:10:59

+0

非常感谢。 – Sebastian 2010-02-09 14:29:55

0

三种意见:

  1. 单元测试通常是小规模,快速的测试,以覆盖小片的代码。使用数据库进行测试并不是真正的单元测试(即使您可以在例如JUnit中运行它们),而是进行系统/集成测试。两者对于不同的目的都很有用。

  2. 即使你的对象图是很大的,我不明白为什么你需要在单元测试一次测试这一切。您使用必要的模拟对象测试一个DAO,并断言对象图的相关部分处理正确。然后编写更多的测试下一个DAO等

  3. IMO的DAO通常不应该做非常复杂的事情(除非业务逻辑的一部分被摆在那里,但是这是很糟糕的设计 - 需要重构,而不是试图掩盖它与扭曲的单元测试)。

+0

非常感谢。 – Sebastian 2010-02-09 14:29:30