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

用EasyMock对模板方法进行部分模拟

司徒捷
2023-03-14

我有几个类遵循“模板方法”模式。抽象类A,具体扩展类B和C,如下所示:

public abstract class A
{
  protected abstract String getData() throws SomeException;

  public void doWork() throws OtherException
  {
    try
    {
      // business logic ...
      String data = this.getData();
      // more business logic ...
    }
    catch(SomeException e)
    {
      log("...", e);
      throw new OtherException("...", e);
    }
  }
}

public Class B extends A
{
  protected String getData() throws SomeException
  {
    // complicated logic relying on lots of dependencies
  }
}

public Class C extends A
{
  protected String getData() throws SomeException
  {
    // different but equally complicated logic relying on lots of dependencies
  }
}

我想编写一个测试来验证当getData()抛出某个Exception时是否抛出其他Exception。我真的希望避免模拟强制getData()抛出所需的所有复杂依赖关系。我不关心getData()如何抛出,我只想让它抛出。所以我想我要的是部分模拟。这就是我所拥有的:

import static org.easymock.EasyMock.*;
....
@Test(expected = OtherException.class)
public void testSomethingOrAnother() throws Exception
{
    B target = createMockBuilder(B.class).addMockedMethod("getData").createMock();

    expect(target.getData()).andThrow(SomeException.class).once();

    replay(target)

    try
    {
        target.doWork(); // expect this to throw OtherException;
    }
    finally
    {
        verify(target);
    }
}

这个测试在我看来很好,但当我运行它时,我得到了这样的结果:

java.lang.Exception: Unexpected exception, expected<OtherException> but was<java.lang.RuntimeException>
    ... deleted for brevity ...
Caused by: java.lang.RuntimeException: Ambiguous name: More than one method are named getData
    at org.easymock.internal.ReflectionUtils.findMethod(ReflectionUtils.java:96)
    at org.easymock.internal.ReflectionUtils.findMethod(ReflectionUtils.java:64)
    at org.easymock.internal.MockBuilder.addMockedMethod(MockBuilder.java:73)
    at org.easymock.internal.MockBuilder.addMockedMethods(MockBuilder.java:92)
    at com.mycompany.more.packages.BTest(BTest.java:83)
    ... deleted for brevity ...
    ... 16 more

需要说明的是:层次结构中的任何地方都没有getData()方法的重载。

EasyMock能做我想做的事吗?我错过了什么?

相关版本编号:

  • EasyMock 3.0
  • JUnit 4.4
  • Java 1.6

共有1个答案

岳承悦
2023-03-14

我认为您的问题可能是addMockedMethod(String)的使用问题。不知道如果没有重载,为什么EasyMock会抱怨方法名称不明确。但以下几点对我起到了作用:

@Test
        public void testSomethingOrAnother() {
            B target = null;
            try {
                target = EasyMock.createMockBuilder(B.class).addMockedMethod(B.class.getDeclaredMethod("getData")).createMock();
                EasyMock.expect(target.getData()).andThrow(new SomeException());
                EasyMock.replay(target);
            } catch (NoSuchMethodException e) {
                fail(e.getMessage());
            } catch (SomeException e) {
                fail(e.getMessage());
            }

            try {
                target.doWork();
                fail("doWork should have thrown an exception");
            } catch (OtherException e) {
                //pass
            }
        }
 类似资料:
  • 我有以下场景: 我想在测试中覆盖公共方法methodA()的catch块。我不想更改私有方法的可见性。是否有任何方法可以使用EasyMock实现私有方法的部分模拟?或者有没有办法改变Junit类中私有方法的行为,以便在不使用mocking的情况下抛出异常? 提前谢谢。

  • 我尝试从以下方法创建单元测试,但我找不到一个解决方案来模拟每个方法内的调用,请您帮助我使用EasyMock为这些方法创建JUnit Test: 提前感谢

  • 我试图在类型s. t上专门化一个类。它忽略了给定类型的恒定性。在这种情况下,该类型是一个模板模板参数: 上面的代码在GCC 4.8.4和clang 5.0(with-std=c 11)中都抱怨bar在与匹配FOFType模板参数化的类一起使用时未定义。即使我删除了sfinae参数,仍然无法找到特化。 这个问题的一个例子可以在这里找到:https://godbolt.org/g/Cjci9C.在上面

  • 问题 定义一个算法的结构,作为一系列的高层次的步骤,使每一个步骤的行为可以指定,使属于一个族的算法都具有相同的结构但是有不同的行为。 解决方案 使用模板方法( Template Method )在父类中描述算法的结构,再授权一个或多个具体子类来具体地进行实现。 例如,想象你希望模拟各种类型的文件的生成,并且每个文件要包含一个标题和正文。 class Document produceDocu

  • 亦称: Template Method 意图 模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 问题 假如你正在开发一款分析公司文档的数据挖掘程序。 用户需要向程序输入各种格式 (PDF、 DOC 或 CSV) 的文档, 程序则会试图从这些文件中抽取有意义的数据, 并以统一的格式将其返回给用户。 该程序的首个版本仅支持 DOC 文

  • 一、定义 模板方法是基于继承的设计模式,可以很好的提高系统的扩展性。 java中的抽象父类、子类 模板方法有两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类。 二、示例 Coffee or Tea (1) 把水煮沸 (2) 用沸水浸泡茶叶 (3) 把茶水倒进杯子 (4) 加柠檬 /* 抽象父类:饮料 */ var Beverage = function(){}; // (1) 把水煮沸