2017-02-23 88 views
2

我该如何测试一个返回布尔值的方法,并且像这样实现?单元测试JPA查询

return entityManager.createQuery("SELECT(i) FROM Items i WHERE o.id=:id", Long.class).setParameter("id", id).getSingleResult() == 1; 

entityManager被注入课堂。

我想我大概应该验证createQuery被调用此查询,然后setParameter被调用id,然后进行比较,然而结果是,没有这样的测试一个简单的代码行像有点大材小用这个? 我特别觉得在单元测试中使用整个select语句会感到不舒服。这似乎更像是我的实现细节。但是,还有什么其他方式来检查查询是否实际检查了COUNT项并执行其他操作?

回答

2

我猜你有这种方法作为某种存储库类的一部分。

我会建议让版本库层离开单元测试套件。 一般而言,您不应该在存储库方法中使用任何逻辑(如果有的话,这些逻辑是微不足道的),或者您至少应该为此努力。

从我个人的经验来看,你最终应该在单元测试的基础上加入一些集成测试套件,并且在集成测试中总是首先在我的列表中存储库方法,并且是其余IT部门的基础试验。

我能想到的唯一例外是当您使用Criteria API有条件地构建您的查询时。但是,再次强调集成测试也是适当的。

那是我的意见,但呼叫是你到底..

+0

用一般的经验法则来增加这个(正确的)答案:用集成测试测试应用程序边界处的代码(在这种情况下是应用程序 - DB);在单元测试中测试只依赖于你的应用的其他“部分”的代码 – crizzis

2

在Java程序单元测试SQL语句是比较困难的,因为你正在穿越“单位”的边界。单元的传统定义是它是一个单独的被测试的类。然而,这并不是非常有用,因为它是一种全有或全无的分类,它会在测试覆盖率上造成巨大的差距,因为没有任何好处。最好是扩展单元测试工具,以支持必须可靠地协同工作的组合单元。

一种方法是创建一个模拟,检查传递的参数并传递适当的返回值。但是,这并不检查逻辑或计算。这可能是必要的第一步。

另一种方法是使用内存数据库,该数据库能够理解您正在使用的SQL类型,并且可以在每次测试或会话开始时填充所需的数据。这将比嘲笑返回值更深入地测试您的设计和代码。它验证你的语法和你的语义,同时速度非常快,是单元测试最有用的属性之一。