模拟继承了受保护的方法

时间:2015-12-11 14:49:15

标签: java unit-testing junit mockito

我这里有我的问题的简化版本。 A类有受保护的方法。 B类继承了这种方法。

public class A{
    protected String getString(){
        //some Code
    }
}


public class B extends A{
    public void doSomething(){
        //someCode
        String result = getString();
    }
}

我现在用Mockito写一个单元测试,这是另一个包测试,我想测试doSomething()方法。要做到这一点,我需要模拟getString() - 调用。由于该方法受到保护且我的测试类位于不同的包中,因此我无法使用doReturn(...).when(classUnderTest).getString()。问题是,我在B级间谍。所以我不能使用mock(new B(), Mockito.CALLS_REAL_METHODS)

我尝试通过Reflection获取受保护的方法:

Method getString = classUnderTest.getClass().getDeclaredMethod("getString");
getString.setAccessible(true);

但我当时不知道如何在doReturn()内使用它。

2 个答案:

答案 0 :(得分:3)

您可以使用'覆盖和子类'

B b = new B() {
  @Override
  protected String getString() {
    return "FAKE VALUE FOR TESTING PURPOSES";
  };
};

答案 1 :(得分:1)

可能有一种更简洁的方法可以做到这一点,但这里有......

  1. 为“A”创建模拟
  2. 创建另一个扩展B的类并覆盖方法
  3. 让重写的方法调用mock
  4. 例如......

    private A partialMock;
    private B classUnderTest;
    
    @Before
    public void setup() {
        partialMock = mock(A.class);
        classUnderTest = new B() {
            @Override
            protected String getString() {
                return partialMock.getString();
            }
        };
    }
    
    @Test
    public void shouldDoSomething() {
    
        when(partialMock.toString()).thenReturn("[THE MOCKED RESPONSE]");
    
        classUnderTest.doSomething();
    
        // ...verify stuff...
    }
    

    显然你甚至不需要使用模拟,你可以直接从重写的方法返回一些东西。