对于单元测试,最好是模拟数据层还是使用像derby这样的嵌入式数据库?
我知道这也取决于测试的目的。但如果我去德比,我不必模仿所有的对象,我认为这会更容易。另一方面,我理解这更倾向于集成测试。那么哪一个更常见于单元测试?
感谢。
根据评论更新:
所以我现在配置了德比,但我的经理坚持使用easymock。我们正在使用jpa,我们有大约20个表=>数据模型。那么对于像项目模型这样的每个方法,我应该为其所有方法指定mockedProject的返回类型吗?像getProjectName(),getProjectId()等?我也应该模拟持久性管理器对象。我认为与仅仅配置像derby这样的嵌入式数据库相比,这只是很多。
答案 0 :(得分:2)
对于单元测试,我建议模拟您的数据层。这清楚地表明您没有测试数据层的功能,也增加了单元测试的速度。
在进行集成测试时,您应该有一个连接到数据层的实时数据库,我更喜欢使用与生产中使用的相同类型的数据库来限制稍后引入新错误的风险。另外,我建议让每个测试都构建自己的测试数据,然后将其删除,因为这样可以确保每个测试都不受其他测试用例中与测试数据交互的影响。
答案 1 :(得分:2)
首先,如果在单元测试中使用外部组件(如数据库,文件系统等),则不能再称为单元测试,而是集成测试代替。
另一方面引用经典Mocks Aren't Stubs说:
- 伪对象实际上有工作实现,但通常需要一些使它们不适合生产的快捷方式(内存数据库就是一个很好的例子)。
在单元测试中使用假货并没有错。
话虽如此,我建议使用一些快速简单的内存数据库,如h2。嘲弄DataSource
,Connection
,ResultSet
,PreparedStatement
......不值得痛苦。
答案 2 :(得分:1)
如果你正在使用JPA,你不需要模拟你的Project对象,因为它们可能只是愚蠢的POJO,对吧?你需要模拟的只是持久性管理器对象(EntityManager)。在最简单的情况下(如果您使用Mockito或Easymock与'niceMock'),您可能只需要创建模拟并注入它,就是这样。根据您正在测试的内容,您可能希望执行更多操作:验证是否调用了save
或merge
方法,指定它将在{{上返回特定的Project对象1}}打电话等。
模拟EntityManager有几个好处:
嘲笑POJO没有这些好处。执行POJO的代码与模拟POJO一样快。填充POJO可能有点痛苦,但不如设置模拟POJO的行为那么多。而且由于POJO不会(通常)对外部依赖性有很大影响,因此很少需要第三个好处。