2011-11-29 96 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