JUNIT服务测试和DAO层

时间:2014-03-26 04:48:54

标签: unit-testing junit junit4

我在项目中有分层架构,如Controller - >服务 - > DAO。我想为服务层编写JUnit测试用例。现在,由于服务层将在内部调用DAO方法,为什么我要为DAO层编写不同的测试用例,因为它是内部测试的。

有些人说我需要使用mockito来模拟DAO方法。真的需要吗?我不能在测试服务层方法时直接使用原始代码吗?

2 个答案:

答案 0 :(得分:3)

为您的服务提供一组测试,并为DAO提供一组单独的测试。

DAO测试应针对数据库,最好是内存数据库。这不仅仅是因为它很容易创建它并在测试中将其拆除,但因为你会知道它是你的而且没有其他人在改变它。 DAO测试将测试您的数据库映射和SQL是否正确。您可以使用DBUnit使用测试数据初始化数据库,并在每次测试结束时验证数据库的内容,以便每个测试都可以针对已知数据集运行。使用单独的DAO测试,如果存在数据库级问题则更容易区分,因为您将在DAO测试中看到它们,而不是在服务测试中看到它们。

可以使用模拟器为DAO测试服务。由于测试不使用数据库,因此它们执行速度更快(针对数据库的测试运行速度慢得多,即使使用内存数据库),您可以在不降低测试速度的情况下运行许多不同的方案。服务层通常是您的大部分复杂性所在,因此需要更多测试来覆盖它,如果这些测试可以快速运行,那就更好了。

通常,您的DAO具有执行crud操作的方法,并且这些方法在服务中以不同方式被反复调用。当您将数据库访问限制为仅DAO测试时,您最小化了测试所需的数据库访问总量,并且测试运行得更快。

你谈到的是,有一组测试对数据库进行一直测试(服务和DAO)是非常诱人的,因为a)它一直在测试真实的东西,而且b)看起来像它将减少工作量(很多时候,项目没有足够的抽象,你可以有效地单独测试事物,而且没有时间来解决问题)。很多项目都是出于明智的原因做出同样的决定,并且他们都直接进入相同的tarpit测试陷阱,这些测试需要花费很长时间才能运行,并且会发现太多的案例(因为开发人员在现有测试中添加更多测试用例时感到气馁已经花了太长时间)。缓慢的测试会导致代码覆盖率下降和测试效率低下。

答案 1 :(得分:1)

在我看来,你应该尽量避免模仿。避免模​​拟的原因是:

  • 您必须确保您的模拟符合您模拟的DAO界面定义的合同。
  • 阅读模拟测试比使用实际实现读取简单单元测试要困难得多。因此,您的测试更可能单独包含错误或具有逻辑流程。一个好的测试是一个易于理解并验证它(可能是)正确的测试。

这并不意味着,你永远不应该使用Mocks,但你应该尽可能多地选择真正的实现。

另一方面,每当实现需要重量级实现或资源(如数据库,JNDI或JMS)时,您都希望使用Mocks。否则,您的测试始终是一种集成测试,需要进行重量级设置并降低测试套件的速度。

我的建议是为需要重量级资源的每种类型提供内存实现,例如数据库,JNDI,JMS等。为了确保它们是真正的替代方案,符合合同,它们必须通过与实际实现相同的测试。 。因此,对于那些具有合同的实施,完整的测试覆盖是强制性的!

从现在开始,你应该找到使用真实实现的地方。对于所有难以测试的情况,如网络错误,数据库连接或协议,我们Mocks。在这种情况下,它们是最好的,但仅在我看来应该减少到这些情况。