如何使用Mockito或任何其他的相关java框架来模拟超类方法

时间:2015-05-19 07:42:56

标签: java junit mocking mockito powermock

我的情景如下

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()方法中存在的方法。

4 个答案:

答案 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 个简单的步骤

  1. 使用PowerMockito.suppress方法和MemberMatcher.methodsDeclaredIn方法抑制父类方法

  2. 第二个在@PrepareForTest中添加父类

  3. 使用 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的运行。然后,您可以模拟“代理”。