Lancelot
Lancelot

Reputation: 2427

JUnit Easymock Unexpected method call

I'm trying to setup a test in JUnit w/ EasyMock and I'm running into a small issue that I can't seem to wrap my head around. I was hoping someone here could help.

Here is a simplified version of the method I'm trying to test:

public void myMethod() {
    //(...)
    Obj myObj = this.service.getObj(param);
    if (myObj.getExtId() != null) {
      OtherObj otherObj = new OtherObj();
      otherObj.setId(myObj.getExtId());
      this.dao.insert(otherObj);
    }
    //(...)
}

Ok so using EasyMock I've mocked the service.getObj(myObj) call and that works fine.

My problem comes when JUnit hits the dao.insert(otherObj) call. EasyMock throws a *Unexpected Method Call* on it.

I wouldn't mind mocking that dao in my test and using expectLastCall().once(); on it, but that assumes that I have a handle on the "otherObj" that's passed as a parameter at insert time... Which of course I don't since it's conditionally created within the context of the method being tested.

Anyone has ever had to deal with that and somehow solved it?

Thanks.

Upvotes: 6

Views: 34875

Answers (4)

Ad Infinitum
Ad Infinitum

Reputation: 3696

Note also that if you use EasyMock.createStrictMock();, the order of the method calls is also important and if you break this rule, it would throw an unexpected method call.

Upvotes: 1

jhericks
jhericks

Reputation: 5971

The anyObject() matcher works great if you just want to get past this call, but if you actually want to validate the constructed object is what you thought it was going to be, you can use a Capture. It would look something like:

Capture<OtherObj> capturedOtherObj = new Capture<OtherObj>();
mockDao.insert(capture(capturedOtherObj));
replay(mockDao);

objUnderTest.myMethod();

assertThat("captured what you expected", capturedOtherObj.getValue().getId(), 
           equalTo(expectedId));

Also, PowerMock has the ability to expect an object to be constructed, so you could look into that if you wanted.

Upvotes: 6

dplass
dplass

Reputation: 1473

You could also use EasyMock.isA(OtherObj.class) for a little more type safety.

Upvotes: 14

DoctorRuss
DoctorRuss

Reputation: 1439

If you can't get a reference to the object itself in your test code, you could use EasyMock.anyObject() as the expected argument to yourinsert method. As the name suggests, it will expect the method to be called with.. well, any object :)

It's maybe a little less rigorous than matching the exact argument, but if you're happy with it, give it a spin. Remember to include the cast to OtherObjwhen declaring the expected method call.

Upvotes: 9

Related Questions