17

所以我一直在使用 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中创建了一个新的模拟,所以它不应该从其他地方继承任何东西(不是其他方法会有一个匹配器)

那么,有什么想法吗?

4

6 回答 6

15

I was sick and tired of seeing this with each new legacy code base with EasyMock I had to work with. Write one new EasyMock test by the book and all of the sudden random tests start failing because of Matchers never captured. So I went looking how EasyMock stores those Matchers. It makes use of a final class LastControl, in that class are a few threadlocals where different things get stored. One of those was for the Matchers. Luck has it that there is a static method on there to pull all the Matchers from the threadlocal that where still on there. So this gave me this idea (with help of a collegue, thanks Sven, he wanted credit)

/**
 * 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();
  }

}

Basicly let your test that fail with the Matchers error extend from this class and you'll be sure the Matchers are cleaned. Note this IS A WORKAROUND. The offending tests should have been written right in the first place. But if you have to wade through 5000+ tests , this is the lesser of two evils. I hope this will help people out !

于 2014-02-19T08:27:53.730 回答
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() 方法的错误测试之后执行的第一个测试,但我还没有通过实验验证这一点。

于 2010-06-10T05:23:43.080 回答
2

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

于 2010-03-25T06:13:27.273 回答
2

我有同样的错误信息。我(意外地)在对被测类的调用中使用了 isA() 声明

IE

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

当我的意思是:

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

每次都失败的是这次测试之后的测试。

于 2010-10-21T16:24:20.647 回答
2

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

似乎 EasyMock 在调用第一个期望方法之前无法抱怨报告的额外匹配器。

于 2011-08-29T18:09:32.847 回答
1

您使用的是哪个版本的 Easymock?
我读了一篇关于v.2.5.2 发布的帖子,以前的版本可能有

捕获中的愚蠢错误

尝试使用 Easymock 2.5.2+

于 2010-05-27T08:26:19.050 回答