当前位置: 首页 > 知识库问答 >
问题:

如何使用Mockito模拟受保护的方法?

宣星光
2023-03-14

我正在使用Mockito 1.9.5。我如何嘲笑从受保护的方法返回的内容?我有这个受保护的方法...

protected JSONObject myMethod(final String param1, final String param2)
{
…
}

然而,当我尝试在JUnit中这样做时:

    final MyService mymock = Mockito.mock(MyService.class, Mockito.CALLS_REAL_METHODS);        
    final String pararm1 = “param1”;
    Mockito.doReturn(myData).when(mymock).myMethod(param1, param2);

在最后一行,我得到一个编译错误“方法‘myMethod’不可见”如何使用Mockito来模拟受保护的方法?如果答案是这样,我愿意升级我的版本。

共有3个答案

赖俊
2023-03-14

您可以使用Spring的ReflectionTestUtils按原样使用类,而无需仅为测试而对其进行更改,也无需将其包装到另一个类中。

public class MyService {
    protected JSONObject myProtectedMethod(final String param1, final String param2) {
        return new JSONObject();
    }

    public JSONObject myPublicMethod(final String param1) {
        return new JSONObject();
    }
}

然后在测试中

@RunWith(MockitoJUnitRunner.class)
public class MyServiceTest {
    @Mock
    private MyService myService;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        when(myService.myPublicMethod(anyString())).thenReturn(mock(JSONObject.class));
        when(ReflectionTestUtils.invokeMethod(myService, "myProtectedMethod", anyString(), anyString())).thenReturn(mock(JSONObject.class));
    }
}
马清野
2023-03-14

根据John B的回答,回复选项3的代码样本请求:

java prettyprint-override">public class MyClass {
    protected String protectedMethod() {
        return "Can't touch this";
    }
    public String publicMethod() {
        return protectedMethod();
    }
}
@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

    class MyClassMock extends MyClass {
        @Override
        public String protectedMethod() {
            return "You can see me now!";
        }
    }

    @Mock
    MyClassMock myClass = mock(MyClassMock.class);

    @Test
    public void myClassPublicMethodTest() {
        when(myClass.publicMethod()).thenCallRealMethod();
        when(myClass.protectedMethod()).thenReturn("jk!");
    }
}
闻人栋
2023-03-14

这不是Mockito的问题,而是普通旧java的问题。从调用方法的地方看,您没有可见性。这就是为什么它是编译时问题而不是运行时问题。

有几个选项:

  • 在模拟类的同一个包中声明您的测试
  • 如果可以,请更改方法的可见性
  • 创建一个扩展模拟类的本地(内部)类,然后模拟这个本地类。因为类是本地的,所以您可以看到该方法
 类似资料:
  • 我尝试模拟父类的受保护方法。因此,我使用&。我的家长班。

  • 我的测试存根是 我在这里做错了什么?

  • 问题内容: 我想模拟一个继承的受保护方法。我不能直接从Java代码中调用此方法,因为它是从另一个包中的类继承的。我找不到指定此方法存根的方法 我查看了重写,这似乎它们仅用于私有方法! 如何指定保护方法? 问题答案: 果壳:不能总是用来对间谍进行打桩;使用。 假设静态导入和(两者): 您也可以设置on 。哪个更有意义取决于实际测试。

  • 问题内容: 关键字授予对相同包和子类(http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html)中的类的访问权限。 现在,每个类都有一个超类(http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html)。 因此,我得出结论,即使每个类都可以访问的方法。

  • 如何使用Mockito或PowerMock模拟一个由子类实现,但从抽象超类继承的受保护方法? 换句话说,我想测试“DoSomething”方法,同时嘲弄“DoSomethingElse”。 抽象超类 子类实现 解决方案 这里给出的答案是正确的,如果涉及的类是在同一包中,将会起作用。 但如果涉及不同的包,一个选择是使用PowerMock。下面的例子对我有效。当然可能有其他的方法,这是一个可行的。 注

  • 问题内容: 我正在尝试使用Mockito 1.8.5存根方法,但是这样做会调用实际方法实现(以“”作为parm值),从而引发异常。 我尝试模拟的方法如下所示。没有最终方法或类。 我正在传递模拟的类如下所示: 是什么导致真正的实现被调用,我该如何防止呢? 问题答案: Mockito代码无法访问您正在模拟的方法。 因为测试代码和被测代码在同一程序包中,所以编译器允许您以这种方式设置模拟,但是在运行时,