13

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

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);

因此,链接对于返回 AutoIndexer 对象的 getNodeAutoIndexer() 不起作用,而对于返回 RelationshipAutoIndexer 的 getRelationshipAutoIndexer() 起作用。两个返回值都被模拟如下:

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

那么可能导致问题的原因是什么?

4

1 回答 1

15

完全没有问题。

让我们检查一下这 4 行代码:

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

第一行创建了一个模拟 indexManager。

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

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

最后一行调用 graphDb.index(),它返回模拟 indexManager(你在第二行告诉它这样做),并要求这个 indexManager(这是你在第一行创建的模拟)在它的 getRelationshipAutoIndexer 方法时返回 relAutoIndexer叫做。

最后一行之所以有效,只是因为您告诉模拟 graphDb 在调用其 index 方法时要返回什么。如果您之前没有这样做过,模拟的 graphDb.index() 方法将返回 null 并且您将拥有一个 NPE。

于 2011-10-29T07:17:03.317 回答