2013-06-21 41 views
1

試圖找出最好的方式來做一些看起來很簡單的事情:測試一個特定的方法在被測試的類上被協調者調用。我使用的Mockito(1.9.5)& PowerMock(1.5.1)與JDK 6.通過間諜與嘲笑的合作者使用PowerMock&Mockito測試方法

一般的方法是通過經由PowerMock的Mockito spy設置的局部模擬中,設置內部狀態WhiteBox方法,然後調用我正在測試的方法:creatFoo()

儘可能簡化了代碼,同時仍然掌握了我所掌握的要點。這裏的類測試:

public class FooGate { 
    BlackBox.Factory factory; 
    BlackBox.Bar bar; 

    public void createFoo(Foo foo) { 
     bar = factory.produce(BlackBox.Bar.class); 

     bar.create(bbFoo); 
    } 
    ... 
} 

下面是不正常的測試:

@RunWith(PowerMockRunner.class) 
@PrepareForTest(FooGate.class) 
public class FooGateTest { 
    @Test 
    public void test() { 

     FooGate testGate = Mockito.spy(new FooGate()); 

     BlackBox.Factory mockfactory = mock(BlackBox.Factory.class); 
     BlackBox.Bar mockBar = mock(BlackBox.Bar.class); 

     WhiteBox.setInternalState(testGate, BlackBox.Factory, mockFactory); 
     WhiteBox.setInternalState(testGate, BlackBox.Bar, mockBar); 

     Foo foo = new Foo(); 
     foo.setSetting("x"); 

     doAnswer(new Answer<Void>() { 
      public Void answer(InvocationOnMock invocation) { 
       ... do stuff ... 
      } 
     }).when(mockBar).create(any(Foo.class)); 

     // NPE here: seems like bar is null in testGate. 
     testGate.createFoo(foo); 

     assertStuff(...); 

    } 
} 

如果我刪除WhiteBox.set ......爲Factory我得到factory.produce()的NPE。所以,這似乎工作。

但是doAnswer()顯然不是。或者是其他東西。

完全開放給其他方法來完成同樣的事情,但想知道我在這裏失蹤。

注意:它看起來不像導入問題,所以我省略了它們,但是如果您認爲它們可能有用,我可以包括它們。

+0

您是否嘗試過使用調試器運行,以查看對「WhiteBox.setInternalState」的調用是否真的在做你期望的? –

+0

請嘗試以下操作並回報。 1.不要監視被測試的班級。在上述測試中我沒有看到有任何理由這麼做。 2.將setter方法添加到被測試的類中,並刪除使用WhiteBox。 –

+0

@DavidWallace我做到了。沒有'setInernalState(mockFactory)''我在'factory.unimportant()'得到一個NPE。 – 6cef

回答

0

我遇到的問題非常簡單。在這個問題的第一個版本中也無法看到。

問題是當我通過WhiteBox.setInternalState()設置的Factory上的produce()被調用時,該方法沒有正確存根,因此它返回null。因此bar在我試圖撥打bar.create()時爲空:因此NPE。

修正通過適當磕碰produce(),在FooGateTest

when(mockfactory.produce((Class)anyObject())).thenReturn(mockBar); 

...並測試通過,沒有錯誤。