EasyMock 3.0, mocking class throws java.lang.IllegalStateException: no last call on a mock available

Nathan Reese picture Nathan Reese · Aug 16, 2010 · Viewed 53.6k times · Source

Running the following unit test throws the exception: java.lang.IllegalStateException: no last call on a mock available


import org.easymock.*;
import org.junit.*;

public class MyTest {

    @Test
    public void testWithClass() {
        Thread threadMock = EasyMock.createMock(Thread.class);
        EasyMock.expect(threadMock.isAlive()).andReturn(true);
    }
}

I am not sure what I am doing wrong and can not find any good examples on the web. How do you mock a class using EasyMock 3.0. What is wrong with the above unit test? Any help would be greatly appreciated.

My project includes the following maven dependencies

<dependency>
   <groupId>org.easymock</groupId>
   <artifactId>easymock</artifactId>
   <version>3.0</version>
   <scope>test</scope>
</dependency>
<dependency>
   <groupId>cglib</groupId>
   <artifactId>cglib-nodep</artifactId>
   <version>2.2</version>
   <scope>test</scope>
</dependency>
<dependency>
   <groupId>org.objenesis</groupId>
   <artifactId>objenesis</artifactId>
   <version>1.2</version>
   <scope>test</scope>
</dependency>

Answer

Rog&#233;rio picture Rogério · Feb 15, 2011

The reason for this exception is that Thread#isAlive() is a final method, but EasyMock does not support the mocking of final methods. So, the call to this method which appears inside EasyMock.expect(...) is not seen as a "call on a mock".

To mock final methods you would need a different mocking tool, such as JMockit (which I develop):

public void testMockingFinalMethod(@Mocked("isAlive") Thread mock)
{
    new Expectations()
    {{
        mock.isAlive(); result = true;
    }};

    assertTrue(mock.isAlive());
}

The mocking API doesn't actually require that methods to be mocked are specified explicitly, in the general case. The Thread class is a tricky one, though.