6

I'm having a strange problem with Easymock 3.0 and JUnit 4.8.2. The problem only occurs when executing the tests from Maven and not from Eclipse.

This is the unit test (very simple):

...
protected ValueExtractorRetriever mockedRetriever;
...

@Before
public void before() {
    mockedRetriever = createStrictMock(ValueExtractorRetriever.class);
}

@After
public void after() {
    reset(mockedRetriever);
}

@Test
public void testNullValueExtractor() { 
    expect(mockedRetriever.retrieve("PROP")).andReturn(null).once();
    replay(mockedRetriever);

    ValueExtractor retriever = mockedRetriever.retrieve("PROP");
    assertNull(retriever);

    assertTrue(true);
}

And I get:

java.lang.IllegalStateException: 1 matchers expected, 2 recorded.

The weird thing is that I'm not even using an argument matcher. And that is the only method of the test! and to make it even worst it works from Eclipse and fails from Maven!

I found a few links which didn't provide me with an answer:

If I change the unit test and add one more method (which does use an argument matcher):

@Test
public void testIsBeforeDateOk() {
    expect(mockedRetriever.retrieve((String)anyObject())).andReturn(new PofExtractor()).anyTimes();
    replay(this.mockedRetriever);

    FilterBuilder fb = new FilterBuilder();
    assertNotNull(fb);

    CriteriaFilter cf = new CriteriaFilter();
    assertNotNull(cf);
    cf.getValues().add("2010-12-29T14:45:23");
    cf.setType(CriteriaType.DATE);
    cf.setClause(Clause.IS_BEFORE_THE_DATE);

    CriteriaQueryClause clause = CriteriaQueryClause.fromValue(cf.getClause());
    assertNotNull(clause);
    assertEquals(CriteriaQueryClause.IS_BEFORE_THE_DATE, clause);

    clause.buildFilter(fb, cf, mockedRetriever);
    assertNotNull(fb);

    Filter[] filters = fb.getFilters();
    assertNotNull(filters);
    assertEquals(filters.length, 1);

    verify(mockedRetriever);

    logger.info("OK");
}

this last method passes the test but not the other one. How is this possible!?!?!

Regards, Nico

More links:

"bartling.blogspot.com/2009/11/using-argument-matchers-in-easymock-and.html"

"www.springone2gx.com/blog/scott_leberknight/2008/09/the_n_matchers_expected_m_recorded_problem_in_easymock"

"stackoverflow.com/questions/4605997/3-matchers-expected-4-recorded"

Community
  • 1
  • 1
Nico
  • 63
  • 1
  • 3
  • Are you using m2eclipse? How does your pom look like? – khmarbaise Apr 14 '11 at 11:36
  • I am. The pom is quite big unfortunately as this is one test of many tests that work (which make this even more weird) from one of many maven modules. The most weird thing is that if I enable the maven-surefire-report and run the threads in parallel, it works! but it depends on the environment (Hudson fails but it works in my dev box) – Nico Apr 14 '11 at 11:43
  • Have you removed your complete local maven repository and tested it from the scratch on your dev-box ? – khmarbaise Apr 14 '11 at 11:46
  • I tried it and I'm experiencing the same problem! This is really weird! as it only happens in a few tests ... Any other ideas? – Nico Apr 14 '11 at 13:13

3 Answers3

5

I had a very similar problem and wrote my findings in the link below. http://www.flyingtomoon.com/2011/04/unclosed-record-state-problem-in.html (just updated)

I believe the problem in on another test that affects your current test. The problem is on another test class and it affects you test. In order to find the place of the real problem, I advice to disable the problematic tests one by one till you notify the failing test.

Actually this is what I did. I disabled the failing tests one by one till I found the problematic test. I found a test that throws an exception and catches by "@extected" annotation without stopping the recording.

lemiorhan
  • 1,434
  • 11
  • 18
  • > Thx a lot!!! I disabled all my tests and went thru all of them until I found one like that and that also lead me to another wrong test class which I fixed and now everything works. Thx for the updated post :) – Nico Apr 18 '11 at 09:22
1

We had this problem recently, and it only reared its head when we ran the entire test suite (1100+ test cases). Eventually, I found that I could put a breakpoint on the test that was blowing up, and then step back in the list of tests that Eclipse had already executed, looking for the previous test case that had set up a mock incorrectly.

Our problem turned out to be somebody using EasyMock.anyString() outside of an EasyMock.expect(...) statement. Sure enough, it was done two tests before the one that was failing.

So essentially, what was happening is that the misuse of a matcher outside of an expect statement was poisoning EasyMock's state, and the next time we tried to create a mock, EasyMock would blow up.

MusikPolice
  • 1,699
  • 4
  • 19
  • 38
  • That is just what I ran into. Calls into PowerMockito.when need to use Matcher.anyString() and EasyMock.expect need to use EasyMock.anyString(). The reason both are needed is that PowerMockito allows mocking static. – toddcscar Jun 27 '19 at 00:18
0

I believe the first error message

java.lang.IllegalStateException: 1 matchers expected, 2 recorded.

means your mockedRetriever methods called twice but test expects it was called once. So your Eclipse and Maven's configuration differs.

And I have no reason to reset mock after test. Just keep in mind JUnit creates new class instance for every single test method.

EDITED:

What about the reason why the last test method passed the answer is:

expect(mockedRetriever.retrieve((String)anyObject())).andReturn(new PofExtractor()).anyTimes();

But in your first test method it is:

expect(mockedRetriever.retrieve("PROP")).andReturn(null).once();

as equivalent of:

expect(mockedRetriever.retrieve("PROP")).andReturn(null);
Constantiner
  • 14,231
  • 4
  • 27
  • 34
  • @Constantiner 1-> `mockedRetriever` is called only once as you can see in the method: `testNullValueExtractor`. I cannot see where 2 "behaviours" have been recorded ... 2-> The reset is there because originally I had more than one test and I reused the same mock and to be honest I didn't know that there were more than one instance being instantiated. Good to know! 3-> I don't understand what you say. The problem is that if I only leave (and remove the other one) the method: `testIsBeforeDateOk` it fails!! That is the problem!!!! 4-> Finally, Maven created my eclipse project and not me. – Nico Apr 14 '11 at 13:12
  • Ah sorry! I didn't have a look that you there is no class under test in your first code and you just calling mock object directly. What if you add `verify(mockedRetriever);` at the end of `testNullValueExtractor()` method in your first code sample? – Constantiner Apr 14 '11 at 13:25
  • @Constantiner I added it and still it fails in "record mode". I'm pretty sure this is not a problem with the test itself but with something else. I'll try disabling the other tests and see if this works as this doesn't actually make any sense, does it? – Nico Apr 14 '11 at 15:12
  • Of course debugging single test is much more simple than a lot of tests at once. – Constantiner Apr 14 '11 at 15:15
  • @Constantiner -> I finally found it! It was a problem as the one @Otuzbesli mentioned in his answer. Thx a lot!!! – Nico Apr 18 '11 at 09:23