2011-10-29 137 views
12

假设我有一个模拟对象,并且我不想存根它的任何方法,但我想存根对象的方法它返回。例如,Mockito - 通过模拟对象方法返回的对象的方法

when(mockObject.method1()).thenReturn(returnValue) 

是它是如何正常完成,但是我正在寻找,

when(mockObject.method1().method2()).thenReturn(returnValue) 

这可能吗?如果我这样做,我会得到一个NullPointerException。目前,我有第一个方法来返回一个模拟对象,然后使用返回的模拟对象,第二个方法存根。然而,这些临时模拟对象对我来说是无用的,并且在将许多方法链接在一起后,会导致大量无用的模拟对象。

编辑:其实,这是可能的链接工程,但我的对象导致NPE。此代码(第一行)是造成NPE:

when(graphDb.index().getNodeAutoIndexer()).thenReturn(nodeAutoIndexer); 
when(graphDb.index().getRelationshipAutoIndexer()).thenReturn(relAutoIndexer); 

但此代码的工作:

IndexManager indexManager = mock(IndexManager.class); 
when(graphDb.index()).thenReturn(indexManager); 
when(indexManager.getNodeAutoIndexer()).thenReturn(nodeAutoIndexer); 
when(graphDb.index().getRelationshipAutoIndexer()).thenReturn(relAutoIndexer); 

所以链接的getNodeAutoIndexer(),而它为它返回一个AutoIndexer对象没有工作getRelationshipAutoIndexer()返回一个RelationshipAutoIndexer。两个返回值都被嘲弄如下:

nodeAutoIndexer = (AutoIndexer<Node>) mock(AutoIndexer.class); 
relAutoIndexer = mock(RelationshipAutoIndexer.class); 

那么会导致什么问题呢?

回答

13

完全没有问题。

让我们来看看这4行代码:

IndexManager indexManager = mock(IndexManager.class); 
when(graphDb.index()).thenReturn(indexManager); 
when(indexManager.getNodeAutoIndexer()).thenReturn(nodeAutoIndexer); 
when(graphDb.index().getRelationshipAutoIndexer()).thenReturn(relAutoIndexer); 

第一行创建一个模拟indexManager。

第二个告诉模拟graphDb在索引方法被调用时返回indexManager(在第一行创建的模拟)。

第三个调用模拟indexManager(在第一行创建),以在其getNodeAutoIndexer方法被调用时返回nodeAutoIndexer。

最后一行调用graphDb.index(),它返回模拟indexManager(你告诉它在第二行做这个),并且询问这个indexManager(它是你在第一行创建的模拟)以返回relAutoIndexer当它的getRelationshipAutoIndexer方法被调用时。

最后一行的作用仅仅是因为你告诉模拟graphDb调用它的索引方法时要返回什么。如果你之前没有这样做,模拟graphDb.index()方法将返回null,你将拥有一个NPE。

+1

谢谢。假设我有很长的功能链,我是否必须重复这个每个功能的存根过程?没有办法让代码让NPE在没有存储索引()的情况下工作?我觉得Mockito应该以某种方式自动将这些方法与基于函数返回类型的模拟对象一起存根,以便我不必直接打扰不需要的存根函数。我只需要这些函数来获得其他功能...... – gsingh2011

+1

不。对于返回对象的方法,默认返回值为null。恕我直言,你遇到的问题是你违反德米特法律的标志:不要与陌生人交谈。 –

+4

请注意,mockito提供了一个深层存根功能('mock(LegacyType。类,RETURNS_DEEP_STUBS)'),但不鼓励它的使用,因为你可能会违反良好的设计法则,比如德米特法则。 请注意,此功能不适用于泛型类型,例如列表。 – Brice