Java 在进行防御性编程时检查业务方法a.k.a中的错误
我开始向大型java代码库添加测试。我经常在测试的会话bean中看到以下内容:Java 在进行防御性编程时检查业务方法a.k.a中的错误,java,unit-testing,junit,stateless-session-bean,defensive-programming,Java,Unit Testing,Junit,Stateless Session Bean,Defensive Programming,我开始向大型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)很容易。当我这样
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。虽然这有点基于观点,但很少有人会说如果给定
null
作为参数返回null
是正确的。如果要添加任何内容,传入null时最多只能是一个IllegalArgumentException
(甚至是NPE
)
可以创建一个测试来检查方法是否以一致的方式失败,但它实际上是在测试JPA提供者的行为,而不是您的代码。应该避免返回空值,它们是所有问题的根源 你可以用这个 或者抛出一个异常、illegalargument或EntityNotex,让人想起它 如果必须返回null,至少将其包装在or use中。一如既往,这取决于:) 如果您正在编写库代码(在其他地方或甚至由其他人共享和使用的代码),那么您应该真正致力于以一致的方式处理所有可思考的输入值。对于库代码来说,使用有良好文档记录的异常而不是返回null无疑是更好的选择 另一方面,还有地方法规。 我可以看到该方法是
public
,但这并不排除它仅用于代码库的一个独立部分的可能性在这种情况下,您不需要对参数和调用者期望的结果进行假设。您可以使用已定义的调用。您可以控制发送的内容以及调用方处理返回值的方式。因此,如果您知道调用方从不发送null,那么不进行null检查是可以的。如果这简化了整个程序结构,那么也可以返回null
ps:在该方法中,最让我困扰的是未处理的NPE,如果
entityManager.find(…)
失败:)那么您会添加一个*异常并保持代码不变?我的任务是将方法参数中的Long改为Long,并保持代码不变。@user1329339将类型从Long改为Long实际上没有什么意义,null只会解析为零。@user1329339我不会添加任何内容。我将进行集成测试,以验证不可能执行将导致null
传递给此方法的操作。@Kayaman感谢您的回复。我添加了一些测试,检查传递null时是否抛出错误,我将添加您建议的测试。@user1329339空值将返回与id 0关联的记录-这可能对您有用,但也可能不适用。