0

对于单元测试,是模拟数据层还是使用像 derby 这样的嵌入式数据库更好?

我知道这也取决于测试的目的。但是如果我选择德比,我不必模拟所有的对象,我认为这会更容易。另一方面,我知道这更倾向于集成测试。那么哪一个更常见于单元测试呢?

谢谢。

根据评论更新:

所以我现在已经配置了 derby,但我的经理坚持使用 easymock。我们正在使用 jpa,我们有大约 20 个表 => 数据模型。那么对于像项目模型这样的每个方法,我应该为其所有方法指定 mockedProject 的返回类型吗?像 getProjectName()、getProjectId() 等?我还应该模拟持久管理器对象。我认为与只配置像 derby 这样的嵌入式数据库相比,这只是很多。

4

3 回答 3

3

首先,如果您在单元测试中使用外部组件(如数据库、文件系统等),它们就不能再称为单元测试,而是集成测试

另一方面,引用经典的Mocks Aren't Stubs说:

  • 对象实际上有工作实现,但通常采取一些捷径,使它们不适合生产(内存数据库就是一个很好的例子)。

在单元测试中使用假货并没有错。

话虽如此,我建议使用一些快速简单的内存数据库,例如。嘲笑DataSource, Connection, ResultSet, PreparedStatement... 只是不值得痛苦。

也可以看看

于 2012-07-18T21:39:55.500 回答
2

对于单元测试,我建议模拟您的数据层。这清楚地表明您没有测试数据层的功能,并且还提高了单元测试的速度。

在进行集成测试时,您应该将实时数据库连接到数据层,我更喜欢使用与生产中使用的相同类型的数据库,以限制以后引入新错误的风险。此外,我建议让每个测试构建自己的测试数据并在之后删除它,因为这样可以确保每个测试不受与其他测试用例中的测试数据交互的影响。

于 2012-07-18T21:36:40.580 回答
1

如果您使用 JPA,则不需要模拟您的 Project 对象,因为它们可能只是愚蠢的 POJO,对吧?您需要模拟的只是持久性管理器对象(EntityManager)。在最简单的情况下(如果您将 Mockito 或 Easymock 与 'niceMock' 一起使用),您可能只需要创建模拟并注入它即可。根据您正在测试的内容,您可能想要做的还不止这些:验证一个saveormerge方法是否被调用,指定它是在get调用时返回一个特定的 Project 对象,等等。

模拟 EntityManager 有几个好处:

  1. 它运行速度非常快——甚至比嵌入式数据库还要快。这些测试将运行很多次,因此它们不会成为太多负担,这一点很重要。
  2. 您不需要填充真实的数据库。尽管对于某些集成测试,您可能无论如何都需要这样做,但很难想出一个涵盖您想要的所有场景的数据库。通过模拟,您可以在测试本身中创建您想要的特定场景。
  3. 您可能想要测试在现实中很难发生的某些条件,例如 IO 错误或数据库中已经存在但违反某些约束的数据。使用模拟,您只需告诉模拟在调用方法时抛出异常。连接到一个真实的数据库(甚至是嵌入式的),实现它是非常困难的(如果不是不可能的话)。

模拟 POJO 没有这些好处。执行 POJO 的代码与执行模拟 POJO 的代码一样快。填充 POJO 可能有点痛苦,但不如设置模拟 POJO 的行为那么痛苦。而且由于 POJO(通常)没有太多的外部依赖关系,因此很少需要第三个好处。

于 2012-07-18T23:06:29.210 回答