23

I am having a problem with EasyMock 2.5.2 and JUnit 4.8.2 (running through Eclipse). I have read all the similar posts here but have not found an answer. I have a class containing two tests which test the same method. I am using matchers.

  1. Each test passes when run alone.
  2. The first test always passes - this is true if I switch the order of the tests in the file.

Here is a simplified version of the test code:

private Xthing mockXthing;
private MainThing mainThing;

@Before
public void setUp() {
    mockXthing = EasyMock.createMock(Xthing.class);
    mainThing = new MainThing();
    mainThing.setxThing(mockXthing);
}

@After
public void cleanUp() {
    EasyMock.reset(mockXthing);
}

@Test
public void testTwo() {
    String abc = "abc";
    EasyMock.expect(mockXthing.doXthing((String) EasyMock.anyObject())).andReturn(abc);
    EasyMock.replay(mockXthing);
    String testResult = mainThing.testCallingXthing((Long) EasyMock.anyObject());
    assertEquals("abc", testResult);
    EasyMock.verify(mockXthing);
}

@Test
public void testOne() {
    String xyz = "xyz";
    EasyMock.expect(mockXthing.doXthing((String) EasyMock.anyObject())).andReturn(xyz);
    EasyMock.replay(mockXthing);
    String testResult = mainThing.testCallingXthing((Long) EasyMock.anyObject());
    assertEquals("xyz", testResult);
    EasyMock.verify(mockXthing);
}

The second (or last) test always fails with the following error:

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

Any insight to this would be greatly appreciated.

Thanks, Anne

Anne
  • 233
  • 1
  • 2
  • 4

4 Answers4

19

I haven't looked meticulously closely yet, but this looks suspect:

String testResult = mainThing.testCallingXthing((Long) EasyMock.anyObject());

anyObject() is a matcher and you're calling it after the replay. It's not used to produce any object. It's used to instruct EasyMock to allow any object. EasyMock is detecting that extra matcher but it is not harmful until the second test. At that point, the number of matchers that EasyMock has recorded but hasn't yet used (2) doesn't line up with the number of parameters expected for the second doXthing call (1).

You should be passing in real parameters to testCallingXthing (or a mock that is in replay mode). Try passing in null directly, or a real value like 2.

Mark Peters
  • 80,126
  • 17
  • 159
  • 190
  • You are correct! I had no need to use the matchers in the line you posted. I could just pass real objects or even null (the real test code has 4 parameters). Thank you so much. – Anne Jul 01 '11 at 16:03
5

for me this failure (in my case 2 matchers expected, 4 recorded.) meant "you are mixing easymock and mockito in the same unit test, so accidentally calling easymock's notNull() method for a mockito argument. Which causes the failure but only if the tests are run in a certain order.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
  • I believe this is my case as well. I tried Mark's answer and it didn't work. The test still fails intermittently. I'm going to rewrite the tests purely in Mockito. – xli Feb 16 '16 at 15:30
  • For me I used an Easymock matcher instead of a Hamcrest macther in an assert. Even though I had reset and replayed in right order it was recording them and causing the next test to fail. This helped me find it. – twinj May 10 '16 at 07:41
  • Finally this was the correct answer for my problem. The correct solution, rebuild tests ussing one framework. The workarround, define an specific execution order. – leon cio May 04 '23 at 09:40
2

Try:

String testResult = mainThing.testCallingXthing(eq(EasyMock.anyLong()));

There are more refined matchers than anyObject(). These allow you to make type-based assertions about collaborators.

From the EasyMock documentation:

eq(X value)
Matches if the actual value is equals the expected value. Available for all primitive types and for objects.
anyBoolean(), anyByte(), anyChar(), anyDouble(), anyFloat(), anyInt(), anyLong(), anyObject(), anyShort()

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
nsfyn55
  • 14,875
  • 8
  • 50
  • 77
0

You should reset mock after each test method to get rid of this problem. Adding below code will solve this problem.

@After 
public void after(){
    EasyMock.reset(mockXthing)
}
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42