2011-02-06 234 views
10

我有這樣一個類:測試代碼

public final class Foo 
{ 
    public native int getBar(); 

    public String toString() 
    { 
     return "Bar: " + getBar(); 
    } 
} 

請注意:getBar()用JNI實現,該類是最後。我想寫一個junit測試來測試toString()方法。爲此,我需要模擬getBar()方法,然後運行原始的toString()方法檢查輸出。

我首先想到的是,這肯定是不可能的,但後來我發現PowerMock與支持根據功能列表最後的測試類和本地方法。但到目前爲止,我沒有成功。我管理的最好的東西是嘲笑完整的課程,但接下來測試測試了模擬的方法,而不是真正意義上的方法。

那麼如何使用PowerMock從上面測試這個toString()方法?我更喜歡使用PowerMock Mockito,但如果這是不可能的,我用EasyMock來代替沒有問題。

回答

8

找到它。我這樣做的方式是正確的。我錯過的唯一的事情是在調用toString()時告訴模擬對象調用原始方法。因此,它的工作原理是這樣的:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ Foo.class }) 
public class FooTest 
{ 
    @Test 
    public void testToString() throws Exception 
    { 
     Foo foo = mock(Foo.class); 
     when(foo.getBar()).thenReturn(42); 
     when(foo.toString()).thenCallRealMethod(); 
     assertEquals("Bar: 42", foo.toString()); 
    } 
} 
+1

HI ......我不能添加 「時()」 ..爲什麼..?你能告訴我使用Easymock – 2015-12-22 07:55:10

1

或者使用策略模式

public final class Foo 
    { 
     public IBarStrategy barStrategy; 

     ...... 
    } 

    interface IBarStrategy{ 
     int getBar(); 
    } 

當單元測試,注入模擬IBarStrategy實例,那麼你可以測試Foo類。

+3

依賴注入對於代碼重用和模塊化是一件好事,但如果不需要,那麼爲什麼我應該增加複雜性並放鬆我的類的API以提高可測性?但這不是重點。假設我不能更改測試主題,因此我無法將本地方法提取到接口中。 – kayahr 2011-02-07 06:24:05

3

或者使用JMockit動態部分嘲諷

import org.junit.*; 
import mockit.*; 

public class FooTest 
{ 
    @Test 
    public void testToString() 
    { 
     final Foo foo = new Foo(); 
     new Expectations(foo) {{ foo.getBar(); result = 42; }}; 

     assertEquals("Bar: 42", foo.toString()); 
    } 
}