6

I have this method signature that i want to mock with EasyMock

public BigDecimal getRemainingPremium(BigDecimal baseAmount, Date commencementDate, Date effectiveDate, boolean isComplete)

My test code has

Premium premium = createMock(Premium.class);
// add this line
EasyMock.expect(premium.getCommencementDate()).andReturn(EasyMock.anyObject(Date.class)).anyTimes();
expect(
    premium.getRemainingPremium(
        EasyMock.anyObject(BigDecimal.class),
        EasyMock.anyObject(Date.class),
        EasyMock.anyObject(Date.class),
        EasyMock.anyBoolean()
    ))
    .andReturn(BigDecimal.TEN).anyTimes();

but i keep getting this matcher exception. I've tried all combinations of primitives and 'EasyMock.anyObject(Boolean.class)'. Any suggestions on a workaround?

java.lang.IllegalStateException: 4 matchers expected, 5 recorded.
This exception usually occurs when matchers are mixed with raw values when recording a method:
    foo(5, eq(6));  // wrong
You need to use no matcher at all or a matcher for every single param:
    foo(eq(5), eq(6));  // right
    foo(5, 6);  // also right
    at org.easymock.internal.ExpectedInvocation.createMissingMatchers(ExpectedInvocation.java:48)
    at org.easymock.internal.ExpectedInvocation.<init>(ExpectedInvocation.java:41)
    at org.easymock.internal.RecordState.invoke(RecordState.java:79)
    at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:41)
Pham Trung
  • 11,204
  • 2
  • 24
  • 43
emeraldjava
  • 10,894
  • 26
  • 97
  • 170
  • 2
    I would add your entire test. Usually when you get the `foo(5, eq(6)); // wrong` error, it is because you haven't used enough matchers, but here the number of matchers used is greater than that expected, so I suspect you are using a matcher after you have called replay. – Dan Temple Mar 21 '14 at 09:23
  • 1
    @DanTemple Sorry - i updated the test code with the extra line (i thought it didn't effect the test). This explains where the 5th matcher is appearing from but i'm unsure how calling replay() will effect this? – emeraldjava Mar 21 '14 at 15:05

1 Answers1

10

You're using a matcher where you should to use an actual object.

EasyMock.expect(premium.getCommencementDate()).andReturn(EasyMock.anyObject(Date.class)).anyTimes();

In the line above, you have used the anyObject() matcher where you really mean to use a Date object.

I wonder if you are confusing matchers with mocks in this sense. The anyObject() matcher is a way of confirming that the method you have mocked is called with an object of type Date. It does not create a date object that can be used as an instance of the Date class. For that you would need to create a mock instance of Date. So, keep in mind that matchers should be used as parameters to mocked methods, but not as return values.

The below expectations will fix your issue:

    Date mockDate = EasyMock.createMock(Date.class);
    final IPremium premium = EasyMock.createMock(IPremium.class);
    EasyMock.expect(premium.getCommencementDate()).andReturn(mockDate).anyTimes();
    expect(
            premium.getRemainingPremium(
                    (BigDecimal) EasyMock.anyObject(),
                    (Date) EasyMock.anyObject(),
                    (Date) EasyMock.anyObject(),
                    EasyMock.anyBoolean()
                    ))
                    .andReturn(BigDecimal.TEN).anyTimes();
    replay(premium);
Dan Temple
  • 2,736
  • 2
  • 22
  • 39