在EJB 3.1的单元测试中模拟容器服务有什么好处?
我想到的可能答案是,
除此之外,您认为还有其他优势吗?
许多人可能知道,可以测试容器提供的一些服务,例如持久性,事务管理(例如使用Bitronix),消息传递(例如,使用Apache ActiveMQ和内存中的JNDI)您自己的JVM中的容器。仍然存在一个论点,即集成测试和单元测试不应该这样做。
据我所知,如果你可以在测试中获得良好的性能,可以使用这些第三方实现进行单元测试,因为你不必花费太多时间进行模拟,而模拟很可能会受到开发人员错误的影响。如果开发人员对模拟没有很好的理解,他可能会最终嘲笑一切,或者换句话说,滥用嘲弄将测试变为“绿色”。这是正确的吗? (请提供您对此的看法)
毕竟,我从未对单元测试有任何可靠的定义:-)。这取决于作者。有些人将“单位”定义为可以测试的最小单位,有些定义“根据上下文,这些可能是单个子程序或由紧密相关单位组成的更大组件。”
感谢。
答案 0 :(得分:3)
如果你有使用容器服务的代码,那么要测试它,你需要模拟这些服务,或者使用真正的实现。你必须做一个或另一个:没有某些服务的实现,你的代码将无法运行,因此无法进行测试。
有时,您可以重构代码以消除对容器服务的直接依赖,这也将消除模拟这些服务的需要。但并非总是如此。
模拟容器服务比使用实际实现提供了更多隔离。它还使您可以更好地控制和深入了解代码的执行。但是,它还涉及编写更多代码,并且随之而来的是,引入错误的风险更大(模拟中的错误,可以直接转换为应用程序代码中的错误)。
有些时候,嘲笑肯定是有道理的。例如,如果您想编写一个测试来检查您的代码是否在UserTransaction上进行了正确的调用,那么通过模拟比尝试检测真实的事务监视器要容易得多。如果你想编写一个检查你的代码是否正确处理特定SQLException的测试,那么没有模拟就几乎不可能做到这一点。
除了这些情况,正如您所指出的,可以使用真实服务编写测试,或者模拟测试。我认为你已经意识到,正统的单元测试方法是模拟它们,或者实际上是包装它们,然后模拟包装器。
这是否真的是必要的,或者是一个好主意,是非常容易辩论的。
StackOverflow不应该用于主观问题,也不应该用于辩论或讨论,所以我对此持怀疑态度。我只想说它与我怀疑的一样 - 正统的'模仿所有移动'的方法是不必要和有害的,而且我们会更好地编写测试而不用嘲笑,覆盖更大的实际代码区域。毕竟,真正的代码是我们要发送给用户的,所以为什么不测试呢?