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

如何在JUnit@Before方法和test方法中使用EasyMock对象

燕飞文
2023-03-14

我试图将EasyMock与JUnit一起使用,但在对JUnit4@before方法中的模拟依赖项调度方法调用时遇到了困难。

在下面的示例中,测试类MockWithBeforeTest正在测试类ClassUnderTest依赖项被传递到ClassUnderTest的构造函数,在构造函数中调用Dependency的方法之一,返回初始化ClassUnderTest所需的值。初始化ClassUnderTest的过程对所有测试都是相同的,所以我用JUnit4@before注释修饰ClassUnderTest#setup方法。

在测试方法ClassUnderTest#GetDevelopy时,我们期望调用mockDependency实例以返回一个值,我们在方法MockWithBeforeTest#TestGetDevelopy中调度该值。但是,这个测试意外失败,出现意外方法调用dependency.getb()错误,尽管这个调用是在MockWithBeforeTest#TestGetDerived中调度的。

我应该如何修改示例代码,使MockWithBeforeTest#TestGetDerived通过?

import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import org.easymock.EasyMockRule;
import org.easymock.Mock;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

public class MockWithBeforeTest {

  @Rule
  public EasyMockRule rule = new EasyMockRule(this);

  @Mock
  private Dependency dependency;

  private ClassUnderTest classUnderTest;

  @Before
  public void setUp() {
    expect(this.dependency.getA()).andReturn(2);
    replay(this.dependency);

    this.classUnderTest = new ClassUnderTest(this.dependency);
    verify(this.dependency);

  }

  @Test
  public void testGetDerived() {
    expect(this.dependency.getB()).andReturn(3);
    replay(this.dependency);

    assertEquals(6, this.classUnderTest.getDerived(1));
    verify(this.dependency);
  }

}

class ClassUnderTest {
  private int a;
  private Dependency dependency;

  ClassUnderTest(Dependency dependency) {
    this.a = dependency.getA();
    this.dependency = dependency;
  }

  void setA(int val) {
    this.a = val;
  }

  int getDerived(int val) {
    return val * this.a * this.dependency.getB();
  }

}

class Dependency {
  private int a;
  private int b;

  Dependency(int a, int b) {
    this.a = a;
    this.b = b;
  }

  int getA() {
    return this.a;
  }

  int getB() {
    return this.b;
  }

}
java.lang.AssertionError: 
  Unexpected method call Dependency.getB():
    at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:44)
    at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:101)
    at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:97)
    at Dependency$$EnhancerByCGLIB$$6d3a4341.getB(<generated>)
    at MockWithBeforeTest.testGetDerived(MockWithBeforeTest.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.easymock.internal.EasyMockStatement.evaluate(EasyMockStatement.java:43)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

上面给出的示例代表了一个一般问题,在这个问题中,传递给被测试类的依赖项比依赖项复杂得多。

  • java:1.8.0_201
  • JUnit:4.12
  • EasyMock:4.2

共有1个答案

羊舌光赫
2023-03-14

更多的研究和与同事的讨论产生了一个解决方案。我错过的步骤是使用easymock.reset(this.dependency)重置模拟的dependency对象,以允许在测试方法中添加额外的预期调用。固定的MockWithBeforeTest

public class MockWithBeforeTest {

  @Rule
  public EasyMockRule rule = new EasyMockRule(this);

  @Mock
  private Dependency dependency;

  private ClassUnderTest classUnderTest;

  @Before
  public void setUp() {
    expect(this.dependency.getA()).andReturn(2);
    replay(this.dependency);

    this.classUnderTest = new ClassUnderTest(this.dependency);
    verify(this.dependency);
    reset(this.dependency); // Allow additional expected method calls to be specified
                            // in the test methods

  }

  @Test
  public void testGetDerived() {
    expect(this.dependency.getB()).andReturn(3);
    replay(this.dependency);

    assertEquals(6, this.classUnderTest.getDerived(1));
    verify(this.dependency);
  }

}
 类似资料:
  • “添加了更多详细信息” 我想模拟某个空方法,但我不太确定如何。我读过EasyMock,但我不知道当它是一个空方法时该怎么办,这是我的主类; 主类 我想模拟这样我就可以跳过尝试 更新程序类 <代码> 私有void方法 这是我目前为止的测试课, (编辑)谢谢。

  • 问题内容: 我已经看到了一些与此相关的问题,但是对于我的特定问题,我似乎无法理解任何答案。 我有一个模拟对象,让我们调用“ object1”,将其发送到某种测试方法,让我们调用testMethod()。所以我最后打电话 用于检测。现在在这个testMethod的某个地方,它将有一部分调用方法 这是一个无效方法。如果方法像 它实际上会返回什么,我通常会这样做 但是,这是一个无效方法,我只想测试一下它

  • 您好,我对Junit和Mockito的单元测试相当陌生。我认为我对这些原则有一个相当合理的理解,但我似乎找不到任何解释来解释我特别想在网上测试什么。 我想测试一个方法,它调用其他几个方法(void和non-void),该方法还实例化了方法体中的对象。不幸的是,我不能分享代码,因为它不是我的,但这里有一个通用格式: 目前我只关心测试method_1,我不能直接测试,因为它是一个私有方法,所以我必须通

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

  • 模拟由某个类实现的接口方法很容易,但如果有一个类并且有一个静态方法,那么我们如何借助easymock对其进行模拟呢?? supose是一个a类,有一个void retruned方法作为公共静态void methodA(一些参数…){} 我们如何在EasyMock的帮助下模仿A的方法methodA

  • 问题内容: 比方说,我有一个名为测试类有几种方法,,,等,每个注释。 现在让我们说我将子类归类为,并且我不会覆盖任何内容。目前是空的。 当我从运行测试,方法,以及因为测试运行不从类和基类的测试方法区分是通过测试运行执行。 如何强制测试运行程序放弃基类的测试? 问题答案: 重组您的测试类。 如果您不想使用基类中的测试,则不要扩展它 如果您需要基类的其他功能,请将该类一分为二-测试和其他功能