【问题标题】:how to mock methods of my superclass using Mockito如何使用 Mockito 模拟我的超类的方法
【发布时间】:2015-09-24 17:36:31
【问题描述】:

我在模拟没有引用的方法的数据时遇到问题,例如 getMethod();不知道模拟框架如何知道它。下面是面临问题的代码,无法在我的代码中设置 HttpRequest 和 URIInfo。

是否可以绕过该方法。

Class A {

private HttpServletRequest httpRequest;
private UriInfo uriInfo;

public HttpServletRequest getReq() {
    return httpRequest;
}
public void setReq(HttpServletRequest req) {
    this.httpRequest = req;
}


public UriInfo getUriInfo() {
    return uriInfo;
}
public void setUriInfo(UriInfo uriInfo) {
    this.uriInfo = uriInfo;
}}



class B extends A {

// some code

}

class C extends B {

protected Object executeCall(Object beIn) throws Exception{

prepareUpdateConfigurationRequest();
// some other methods.
return "";
}
private void prepareUpdateConfigurationRequest() {
implPutCustomerProductOrderIdProductConfigurationsImpl.setReq(getReq());
implPutCustomerProductOrderIdProductConfigurationsImpl.setUriInfo(getUriInfo());
}}

// 使用 Mockito 框架测试类

@RunWith(MockitoJUnitRunner.class)
public class CTest {

@Mock
private A a = Mockito.mock(A.class);
@InjectMocks
private C c = new C();

private ImplBackEndInput implBackEndInput;

@Test
public void testExecuteCallObject() {



    implBackEndInput = new ImplBackEndInput();

    UriInfo uriInfo = Mockito.mock(UriInfo.class);

    Mockito.when(a.getUriInfo()).thenReturn(uriInfo);
    Mockito.when(a.getReq()).thenReturn(httpServletRequest);

    try {
        c.executeCall(implBackEndInput);
    } catch (Exception e) {
    }

}
}

【问题讨论】:

  • 如何从可见性为protected 的测试类中调用executeCall
  • @InjectMocks private C c = new C();
  • 您可以尝试添加以下代码行吗?

标签: java unit-testing mockito


【解决方案1】:

无法使用 Mockito 模拟受保护或私有方法,我建议如果您使用 spring 在测试包中创建一个 DummyC 类,将其作为 springConfig 中的父级引用,并使其在被调用时仅返回对象.这样,该类将使用该方法作为您不需要测试的真实类的旁路。

【讨论】:

    【解决方案2】:

    鉴于对非静态方法的一些静态引用 - A.getUriInfo() - 以及各种其他错误,我不太确定您的代码是如何编译的。使用 getter 为同一个对象调用 setter 也没有多大意义:

    implPutCustomerProductOrderIdProductConfigurationsImpl.setReq(getReq());
    implPutCustomerProductOrderIdProductConfigurationsImpl.setUriInfo(getUriInfo());
    

    但要为可能在这里结束的其他人回答您的问题,您根本不需要在测试类中模拟 A 类(此处):

    Mockito.when(A.getUriInfo()).thenReturn(uriInfo);
    Mockito.when(A.getReq()).thenReturn(httpServletRequest);
    

    你真的根本不需要这两行。其实你可以完全去掉A的mock(这一行):@Mock private A a = Mockito.mock(A.class);

    相反,只需这样做:

    c.setUriInfo(uriInfo);
    c.setReq(httpServletRequest);
    

    这是因为 C 扩展了 A,这意味着 A 的所有方法,当没有被覆盖时,都被 C 继承。所以如果你在 C 的实例上调用非覆盖的 setter 方法,它将直接转到 A 的方法. 调用如上所示的set方法后,当你调用c.getUriInfo()时,它会将你传入的对象作为参数返回给setUriInfo(uriInfo);方法。这里根本不需要嘲笑。

    【讨论】:

    • 对大写 A 的混淆表示歉意 .. 已在代码中更正。
    • 除了语法错误之外,我的回答仍然是正确的。您不需要模拟对a.getUriInfo() 的调用,只需调用c.setUriInfo(uriInfo),这将导致返回正确的对象。这是由于 java 继承。
    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 2020-12-08
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    相关资源
    最近更新 更多