2011-11-29 93 views
16

我想模擬一種繼承的受保護方法。我不能直接從java代碼調用此方法,因爲它是從另一個包中的類繼承的。我無法找到一個方法來指定這個方法來,踩在when(...)嘲諷保護方法

package a; 

public class A() { 
    protected int m() {} 
} 

package b; 

public class B extends a.A { 
    // this class currently does not override m method from a.A 
    public asd() {} 
} 

// test 
package b; 

class BTest { 
    @Test 
    public void testClass() { 
     B instance = PowerMockito.spy(new B()); 
     PowerMockito.when(instance, <specify a method m>).thenReturn(123); 
     //PowerMockito.when(instance.m()).thenReturn(123); -- obviously does not work 
    } 
} 

我看着PowerMockito.when覆蓋,這似乎是他們都只有私有方法!

如何指定受保護的方法?

+0

@AndroidKiller,用類名更新代碼。其實它們可能來自Mockito,但我使用powermock,這些方法的含義與此相同 –

+0

這就是爲什麼我們總是應該比繼承更喜歡構圖。如果你不能在你的測試代碼中重新定義這種方法,就像你會用遺留代碼一樣。 – Brice

回答

24

堅果殼:不能總是使用when來殘留間諜;使用doReturn

假設spydoReturn靜態進口(包括PowerMockito):

@RunWith(PowerMockRunner.class) 
@PrepareForTest(B.class) 
public class BTest { 
    @Test public void testClass() throws Exception { 
     B b = spy(new B()); 
     doReturn(42).when(b, "m"); 
     b.asd(); 
    } 
} 

@PrepareForTest(A.class)並可以在when(a, "m")建立doReturn。哪個更有意義取決於實際測試。

+0

哇,謝謝。有趣的是,當我嘗試使用Method實例而不是方法字符串名稱stubbing失敗,出現關於錯誤數量參數的異常消息。但是,字符串名稱完美無缺。 –

+0

@mishanesterenko是的,它有時會變得有點複雜。爲了測試的目的,另一個選項總是將'B'分類。並不總是一個選項,但比修改字節碼更「神奇」;) –

+0

如果將Methode設置爲void,你會怎麼做。假設'm'是一個像void m(MySpecialParser解析器)這樣的set-Methode。這個解析器用於解析我的文本。我怎麼嘲笑它? – Kayser