1

我开始向大型 Java 代码库添加测试。我经常在我正在测试的会话 bean 中看到以下内容:

public OrderDTO getOrderDTO(Long id) {
    Order o = (Order)entityManager.find(Order.class, id);
    OrderDTO dto = new OrderDTO(o.getId(), o.getCurrency());
    return dto;
}

编写单元测试来破坏此代码(发送空或不存在的 id)很容易。当我这样做时,团队的一半开发人员说:

我们不会对所有内容进行错误检查。如果你的参数是垃圾,你会很快知道的!

另一半说:

我们必须将 ifs 添加到 id,然后添加到 o,如果其中任何一个为 null,则返回 null。

单元测试的目的不是准确地找到这些问题吗?(是的,我在征求意见!)

是的,从 Long 切换到 long 将删除一个 if。

4

3 回答 3

2

null虽然这有点基于意见,但很少有人会说如果null作为参数给出返回是正确的。如果我要添加任何内容,则在传入 null 时最多是 a IllegalArgumentException(甚至是NPE)。

可以创建一个测试来检查该方法是否以一致的方式失败,但它实际上是在测试 JPA 提供者的行为,而不是您的代码。

于 2015-08-17T12:12:08.363 回答
1

应该避免返回空值,它们是万恶之源。

您可以使用Null Object Pattern

或者抛出异常、非法参数或实体注解。

如果你必须返回 null,至少将它包装在一个可选的或使用guava中。

于 2015-08-17T12:26:35.457 回答
0

一如既往,这取决于:)

如果您正在编写库代码(在其他地方甚至由其他人共享和使用的代码),那么您应该真正致力于以一致的方式处理所有可想到的输入值。对于库代码,使用有据可查的异常而不是返回 null 肯定是更可取的。

另一方面,有本地代码。我可以看到该方法是public,但这并不能消除它仅用于代码库的一个孤立部分的可能性。
在这种情况下,您不会使用有关参数的假设以及调用者期望的回报。您使用已定义的调用。您可以控制发送的内容以及调用者如何处理返回值。因此,如果您知道调用者从不发送空值,则可以不进行空值检查。如果这可以简化您的整体程序结构,也可以返回 null 。

ps:该方法中最困扰我的是如果entityManager.find(..)失败则未处理的NPE :)

于 2015-08-17T13:45:33.880 回答