在套件测试期间,EasyMock表示0匹配器预计会有1个记录

时间:2010-02-19 01:49:38

标签: easymock matcher

所以我一直在使用EasyMock的类扩展。突然间我得到了这个异常,但只有当我运行整个测试套件时才会出现:

java.lang.IllegalStateException: 0 matchers expected, 1 recorded.
at org.easymock.internal.ExpectedInvocation.createMissingMatchers(ExpectedInvocation.java:42)
at org.easymock.internal.ExpectedInvocation.<init>(ExpectedInvocation.java:34)
at org.easymock.internal.ExpectedInvocation.<init>(ExpectedInvocation.java:26)
at org.easymock.internal.RecordState.invoke(RecordState.java:64)
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:24)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:56)
at org.easymock.classextension.internal.ClassProxyFactory$1.intercept(ClassProxyFactory.java:74)
at com.protrade.soccersim.data.emulator.matrix.PositionCategoryMatrix$$EnhancerByCGLIB$$c5298a7.getPossession(<generated>)
at com.protrade.soccersim.data.emulator.stats.team.PossessionCalculatorUnitTest.testDeterminePossessionHomeWin(PossessionCalculatorUnitTest.java:45)

所涉及的代码就是这个小小的美女(修剪了一下):

    @Before
public void setUp() throws Exception {
    homeTeam = createMock( PositionCategoryMatrix.class );
    awayTeam = createMock( PositionCategoryMatrix.class );
    ...
}

@Test
public void testDeterminePossessionHomeWin() {
    expect(homeTeam.getPossession()).andReturn( 0.15151515 );
    expect(awayTeam.getPossession()).andReturn( 0.01515152 );
    replay( homeTeam, awayTeam );
    ...
}

第一个期望是抛出异常。它真的没有意义。它说这是一个匹配器,但该方法甚至没有争论。奇怪的是,这只是在测试套件中!我正在@Before中创建一个新的模拟,所以它不应该从其他地方继承任何东西(不是其他方法会有一个匹配器)

那么,有什么想法吗?

6 个答案:

答案 0 :(得分:11)

我厌倦了使用EasyMock的每个新遗留代码库看到这一点我必须使用。本书写了一个新的EasyMock测试,由于Matchers从未捕获过,所有突然的随机测试都开始失败。所以我去了解EasyMock如何存储这些Matchers。它使用了最后一个类LastControl,在该类中有一些threadlocals,其中存储了不同的东西。其中一个是Matchers。幸运的是,有一个静态方法可以将所有Matchers从仍然在那里的threadlocal中拉出来。所以这给了我这个想法(在一位同事的帮助下,谢谢Sven,他想要信用)

/**
 * Base class to make sure all EasyMock matchers are cleaned up.  This is not pretty but it will work
 * 
 * @author N069261KDS
 *
 */
public class BaseTest {

  @Before
  public void before(){
    LastControl.pullMatchers();
  }

  @After
  public void after(){
    LastControl.pullMatchers();
  }

}

基本上让你的测试失败并且Matchers错误从这个类扩展,你将确保Matchers被清理。请注意,这是一个替代方法。应该首先写出违规测试。但是,如果你不得不涉及5000多个测试,这是两个邪恶中的较小者。我希望这会帮助别人!

答案 1 :(得分:4)

虽然这可能是由于“愚蠢”的EasyMock错误导致的虚假消息,但也很可能是由于EasyMock API的无效使用造成的。在我的情况下,消息来自于这个JUnit 3.8测试(和你一样,这只发生在我运行我的整个测试套件时,并且只通过Maven,而不是Eclipse):

public void testSomething() {
    // Set up
    MyArgumentType mockArg = (MyArgumentType) EasyMock.anyObject(); // bad API usage

    // Invoke the method under test
    final String result = objectUnderTest.doSomething(mockArg);

    // Verify (assertions, etc.)
    ...
}

我应该使用createMock(MyArgumentType.class)或其变体之一,而不是使用anyObject()。我不知道我在想什么,我已经写了数百万次这些测试并正确使用了API。

令人困惑的一点是,使用“错误数量的匹配器”消息失败的测试不一定(或曾经?)错误地使用API​​的测试。它可能是在包含replay()或verify()方法的错误之后执行的第一个测试,但我还没有通过实验验证。

答案 2 :(得分:2)

我有同样的错误消息。我(不小心)在测试类

的调用中使用了isA()声明

classUnderTest.callStateChanged(calls, isA(LoggingOnlyListener.class));

当我的意思是:

classUnderTest.callStateChanged(calls, new LoggingOnlyListener());

这是每次失败后的测试。

答案 3 :(得分:2)

我刚遇到这个问题,我想我设法解决了这个问题。对我来说,这是由于之前的测试(在不同的类中),我在Assert.assertEquals方法中(错误地)使用EasyMock匹配器。

似乎EasyMock不会抱怨额外的匹配器报告,直到第一个预期的方法被调用。

答案 4 :(得分:1)

我遇到了类似的问题。根据我的观察,使用Matchers匹配甚至方法返回。因此,如果您的第一个方法因任何原因失败,则返回匹配的匹配器仍在堆栈中。即使您的方法没有采用任何参数,这也可能是您看到1个匹配器记录的原因之一。基本上,第一个方法调用永远不会返回值。

答案 5 :(得分:1)

您使用的是哪个版本的Easymock?
我读了post关于v.2.5.2版本的内容,而前言版本可能有

  

捕获中的愚蠢错误

尝试使用Easymock 2.5.2 +