【问题标题】:mocking a superclass method with EasyMock使用 EasyMock 模拟超类方法
【发布时间】:2014-02-01 21:11:20
【问题描述】:

我的类层次结构如下:

public class Parent {
    public int parentMethod(...) {...}
}

public class Child extends Parent {
    public int childMethod(...) {...}
}

我想模拟出Child 类的一个实例,但parentMethod 经常在该对象上调用(以及childMethod)。当我尝试在 parentMethod 调用上使用 expect() 时,默认的 EasyMock 行为是使用 real parentMethod,但这不起作用,因为父类中有一堆状态我不想嘲笑。有没有办法使用createMockBuilder 或任何其他 EasyMock API 来模拟它?

【问题讨论】:

  • 试试 JMockit Expectations API

标签: java unit-testing easymock


【解决方案1】:

我认为您正在考虑的是部分模拟。

部分模拟允许您模拟具有特定功能(特定方法)的真实对象。所以调用parentMethod时会使用真实状态,但childMethod可以被mock。

然后您设置您的期望并以与完全模拟对象相同的方式验证模拟。

就在 EasyMock 中创建一个而言,类似这样的方法可以解决问题:

    final IMockBuilder<Child> mockBuilder = EasyMock.createMockBuilder(Child.class);
    mockBuilder.addMockedMethod("childMethod");
    final Child mockedChild = mockBuilder.createMock();

    EasyMock.expect(mockedChild.childMethod()).andReturn(1);
    EasyMock.replay(mockedChild);

    //Whatever else happens in your test

    EasyMock.verify(mockedChild);

【讨论】:

    【解决方案2】:

    从您的问题中我可以理解。你不想模拟 parentClass{ }。

    你可以试试这个。

    objenesis = new ObjenesisStd(); // or ObjenesisSerializer
     obj_1 = objenesis.newInstance(Child.class);
     method = obj_1.getClass().getDeclaredMethod("childMethod",NULL);
     method.setAccessible(true);
     method.invoke(obj_1,NULL);
    

    通过这种方法,您可以只模拟子类,而不依赖任何父类。

    【讨论】:

      【解决方案3】:

      在最初的问题发生六年后,我刚刚遇到了我认为 OP 真正要问的问题:如何模拟子类并让父类中的所有方法也被模拟?如果是这样的话,这里的其他答案(处理部分模拟)就不合适了。

      无论如何,这只是发生在我身上。当我嘲笑子类时,父母的真实方法被调用了。答案?父方法声明为final,因此EasyMock 无法在模拟的子类中覆盖它。删除 final 声明将其清除,该方法现在已被模拟。

      现在,关于部分模拟的建议并不是没有用的:我通过尝试通过部分模拟来模拟该方法来解决这个问题,这时 EasyMock 告诉我它做不到。当只使用毯子createMock 方法时,它会以前面描述的方式默默地表现。

      希望这对将来的人有所帮助。

      干杯, 史蒂夫

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多