我在模仿EntityManager的时候得到了NPE,下面是我的代码。
@Stateless
public class NodeChangeDeltaQueryBean implements NodeChangeDeltaQueryLocal {
@PersistenceContext
private EntityManager em;
@Override
public String findIdByNaturalKey(final String replicationDomain, final int sourceNodeIndex,
final int nodeChangeNumber) {
List<String> result =
NodeChangeDelta.findIdByNaturalKey(this.em, replicationDomain, sourceNodeIndex,
nodeChangeNumber).getResultList();
return result.isEmpty() ? null : result.get(0);
}
}我的实体类
@Entity
public class NodeChangeDelta implements Serializable, Cloneable, GeneratedEntity, KeyedEntity<String> {
public static TypedQuery<String> findIdByNaturalKey(final EntityManager em, final String replicationDomain, final int sourceNodeIndex, final int nodeChangeNumber) {
return em.createNamedQuery("NodeChangeDelta.findIdByNaturalKey", String.class)
.setParameter("replicationDomain", replicationDomain)
.setParameter("sourceNodeIndex", sourceNodeIndex)
.setParameter("nodeChangeNumber", nodeChangeNumber);
}
}我的测试类
@RunWith(MockitoJUnitRunner.class)
public class NodeChangeDeltaQueryBeanTest {
@InjectMocks
NodeChangeDeltaQueryBean nodeChangeDeltaQueryBean;
@Mock
EntityManager em;
@Test
public void testFindIdByNaturalKey() {
this.addNodeChangeDelta();
this.nodeChangeDeltaQueryBean.findIdByNaturalKey(this.REPLICATION_DOMAIN,
this.SOURCE_NODE_INDEX, this.NODE_CHANGE_NUMDER);
}
}在实体类中调试em is not null (以及其他参数REPLICATION_DOMAIN,SOURCE_NODE_INDEX,NODE_CHANGE_NUMDER not null),而em.createNamedQuery("NodeChangeDelta.findIdByNaturalKey",String.class)为null。
发布于 2015-04-06 20:20:11
在mockito wiki上:Don't mock types you don't own !
这不是一条硬线,但越过这条线可能会产生影响!(它很可能会。)
相反,最常见的方法是在外部库/系统周围创建包装器,尽管人们应该意识到抽象泄漏的风险,其中太多低级API、概念或异常超出了包装器的边界。为了验证与第三方库的集成,编写集成测试,并使其尽可能紧凑和可读。
没有控件的模拟类型可以被认为是(模拟)反模式。虽然EntityManager几乎是标准的,但人们不应该认为在即将到来的JDK / JSR版本中不会有任何行为变化(它已经在API的其他部分发生过很多次,看看JDK发行说明就知道了)。此外,真正的实现可能在其行为中具有难以模仿的微妙之处,测试可能是绿色的,但生产tomcats是着火的(真实故事)。
我的观点是,如果代码需要模拟我不拥有的类型,设计应该尽快更改,这样我、我的同事或该代码的未来维护者就不会落入这些陷阱。
此外,wiki链接到其他博客条目,这些条目描述了他们在尝试模拟他们无法控制的类型时遇到的问题。
相反,我真的建议每个人在测试与另一个系统的集成时,不要使用模拟。我相信对于数据库来说,Arquillian是最好的选择,这个项目看起来相当活跃。
改编自我的答案:
发布于 2015-04-06 20:00:12
在Mockito中,对未显式配置的mock进行的任何方法调用都将返回null。因此,在findIdByNaturalKey中,em.createNamedQuery返回null,因此在setParameter上返回NPE。您需要将其配置为RETURN_MOCKS。
另外,我不确定@InjectMocks是否支持@PersistenceContext。如果不是,则em可能为null。如果是这样,请让我知道,上面是你的问题。
https://stackoverflow.com/questions/29469442
复制相似问题