24

I'm using EasyMock to do some unit tests and I don't understand the usage of EasyMock.expectLastCall(). As you can see in my code below, I have an object with a method that returns void getting called in some other object's method. I would think that I have to make EasyMock expect that method call, but I tried commenting out the expectLastCall() invocation and it still works. Is it because I passed EasyMock.anyObject()) that it registered it as an expected call or is there something else going on?

MyObject obj = EasyMock.createMock(MyObject.class);
MySomething something = EasyMock.createMock(MySomething.class);
EasyMock.expect(obj.methodThatReturnsSomething()).andReturn(something);

obj.methodThatReturnsVoid(EasyMock.<String>anyObject());

// whether I comment this out or not, it works
EasyMock.expectLastCall();

EasyMock.replay(obj);

// This method calls the obj.methodThatReturnsVoid()
someOtherObject.method(obj);

The API doc for EasyMock says this about expectLastCall():

Returns the expectation setter for the last expected invocation in the current thread. This method is used for expected invocations on void methods.
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • This question wasn't what I was looking for, but it combined with the answer and comments from Yogendra helped me understand my issue. Thanks for getting here first. – DaShaun Jun 04 '13 at 15:18

3 Answers3

28

This method returns you the handle of expectation through IExpectationSetters; which gives you ability to validate(assert) that your void method was called or not and related behaviors e.g.

EasyMock.expectLastCall().once();
EasyMock.expectLastCall().atLeastOnce();
EasyMock.expectLastCall().anyTimes();

Detailed API of the IExpectationSetters is here.

In your example you are just getting the handle and not doing anything with it hence you don't see any impact of having or removing the statement. It's very same as you call some getter method or declare some variable and don't use it.

falconepl
  • 398
  • 1
  • 3
  • 15
Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73
  • What do I have to do (or what am I doing) that is making my test expect the invocation of `methodThatReturnsVoid()`? Just calling it before the `replay()`? – Sotirios Delimanolis Dec 17 '12 at 16:08
  • @SotiriosDelimanolis As I mentioned, use `EasyMock.expectLastCall().atLeastOnce();` to assert that your method was successfully called at least once. – Yogendra Singh Dec 17 '12 at 16:33
  • I get that. But if I have no `expectLastCall()`, the test still passes. Shouldn't it fail since you didn't make the mock object expect it? – Sotirios Delimanolis Dec 17 '12 at 17:08
  • @SotiriosDelimanolis Test will pass as this is assertion statement not the execution statement. Hope you understand the difference. Test case you write to validate certain behavior of your code. It depends, what all you want to validate and you need to put the assertions accordingly. – Yogendra Singh Dec 17 '12 at 19:05
  • 5
    Ugh... EasyMock was a good start, but Mockito or JMockit skip these hoops. – Joseph Lust Jun 07 '13 at 16:19
  • @JosephLust: I like [PowerMock](https://code.google.com/p/powermock/). It's very powerful. Try is out. – Yogendra Singh Jun 07 '13 at 20:26
  • @Yogendra Indeed, I use PowerMockito (Powermock with Mockito) :) – Joseph Lust Jun 08 '13 at 21:32
4

You only need EasyMock.expectLastCall(); when you need to further verify anything other than "That the method was called. (same as setting expectation)"

Say you want to verify how many times the method was called so you will add any of :

EasyMock.expectLastCall().once();
EasyMock.expectLastCall().atLeastOnce();
EasyMock.expectLastCall().anyTimes();

Or say you want to throw an exception

EasyMock.expectLastCall().andThrow()

If you don't care then EasyMock.expectLastCall(); is not required and does not make any difference, your statement "obj.methodThatReturnsVoid(EasyMock.<String>anyObject());" is enough for setting up expectation.

anuj arora
  • 831
  • 12
  • 22
Nisarg
  • 109
  • 8
4

You are missing EasyMock.verify(..)

MyObject obj = EasyMock.createMock(MyObject.class);
MySomething something = EasyMock.createMock(MySomething.class);
EasyMock.expect(obj.methodThatReturnsSomething()).andReturn(something);

obj.methodThatReturnsVoid(EasyMock.<String>anyObject());

// whether I comment this out or not, it works
EasyMock.expectLastCall();

EasyMock.replay(obj);

// This method calls the obj.methodThatReturnsVoid()
someOtherObject.method(obj);

// verify that your method was called
EasyMock.verify(obj);
juandiegoh
  • 378
  • 1
  • 9
  • No, the `verify` was implied. The issue is explained in [Yogendra's answer](http://stackoverflow.com/a/13917432/438154). I didn't write my mock expectations properly. – Sotirios Delimanolis Aug 16 '16 at 21:01