【问题标题】:Partial mock of template methods with EasyMock使用 EasyMock 对模板方法进行部分模拟
【发布时间】:2013-05-24 20:02:11
【问题描述】:

我有几个遵循“模板方法”模式的课程。抽象类 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() 抛出 SomeException 时抛出 OtherException。我真的想避免模拟强制 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

【问题讨论】:

    标签: java easymock


    【解决方案1】:

    我认为您的问题可能是使用 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
                }
            }
    

    【讨论】:

    • 谢谢!我试图自己走这条路,但你的反射富比我的要好。 :)
    【解决方案2】:

    使用 Easymock:3.2,您可以指定方法参数的类型。看看IMockBuilder#addMockedMethod(String methodName,Class&lt;?&gt;... parameterTypes) 谢谢。

    【讨论】:

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