我的情景如下
class SuperClass{
public void run(){
System.out.println("I am running in Super class");
}
}
class ChildClass extends SuperClass{
public void childRunner(){
System.out.println("Step 1");
System.out.println("Step 2");
**run();**
System.out.println("Last Step");
}
}
现在我想模仿childRunner()
的{{1}}方法,因为这个方法在内部调用超类方法,我需要一些关于如何模拟ChildClass
的帮助/代码run()
childRunner()
方法中存在的方法。
答案 0 :(得分:6)
理想情况下,你应该优先考虑构成而不是继承"。
如果你没有这个选项,你可以使用doNothing
,这基本上告诉Mockito在调用mock / spy对象中的方法时什么也不做。这也讨论了here
以下代码示例应该有帮助
@Test
public void tst() {
ChildClass ch = Mockito.spy(new ChildClass());
Mockito.doNothing().when((SuperClass)ch).run();
ch.childRunner();
}
class SuperClass{
public void run(){
System.out.println("I am running in Super class");
}
}
class ChildClass extends SuperClass{
public void childRunner(){
System.out.println("Step 1");
run();
System.out.println("Last Step");
}
}
输出:
Step 1
Last Step
如果你使用super.run();这不会起作用
答案 1 :(得分:1)
这里是一个类的示例,该类扩展了另一个类,并且具有其他一些依赖关系。在这种情况下,我将把超类调用移到另一个方法中,然后模拟超类调用者方法。
class Child extends Parent {
@Autowired
private Dependicy d;
public Authentication authenticate(Authentication auth) {
the code to be tested...
superAuthenticate(auth);// the code that I don't want to deal with it.
return auth;
}
protected Authentication superAuthenticate(Authentication auth) {
return super.authenticate(auth);
}
}
正如您在上面看到的,authenticate方法执行一些逻辑,然后调用超类的方法,因此我想模拟超类调用并测试自己的代码块。这是我的测试课:
@RunWith(MockitoJUnitRunner.class)
public class ChildTest {
@Mock
private Dependicy d;
@InjectMocks
private Child child = new Child();
@Test
public void testSomething() {
Child spy = Mockito.spy(child);
when(d.aMethod(aParam)).thenReturn(aResult);
doReturn(usefulResult).when(spy).superAuthenticate(any());
Authentication result = spy.authenticate(auth);
assertThat(result).isNotNull;
}
}
答案 2 :(得分:1)
我已经回答了抑制超类方法 here 但根据你的问题我正在更新代码如下
我找到了一种使用 PowerMockito 抑制超类方法的方法。只需 3 个简单的步骤
使用PowerMockito.suppress方法和MemberMatcher.methodsDeclaredIn方法抑制父类方法
第二个在@PrepareForTest中添加父类
使用 PowerMock 运行您的测试类,即在您的测试类上方添加 @RunWith(PowerMockRunner.class)。
@RunWith(PowerMockRunner.class)
@PrepareForTest({SuperClass.class})
public class TestChildClass(){
@Spy
private ChildClass testChildClassObj = Mockito.spy(new ChildClass());
@Test
public void testChildRunner(){
PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(SuperClass.class));
//your further test code
testChildClassObj.childRunner();
}
}
注意:这仅在超类方法不返回任何内容时有效。
答案 3 :(得分:-1)
作为快速解决方法,我只是在子类上添加了一个不同的代理方法,该方法调用了super的运行。然后,您可以模拟“代理”。