Re: [powermock] @PrepareForTest in multiple classes

5,729 views
Skip to first unread message

Johan Haleby

unread,
Feb 12, 2013, 9:34:00 AM2/12/13
to powe...@googlegroups.com
Well couldn't it just be that you haven't setup the expections for a static method that is called in ServiceFactory or SomeClassWithStaticMethod during the test?

Regards,
/Johan

On Tue, Feb 12, 2013 at 3:25 PM, Fabian <fabian....@gmail.com> wrote:
Hi

I have a problem with the mocking of static methods. My code looks something like this:

@RunWith(PowerMockRunner.class)
@PrepareForTest(SomeClassWithStaticMethod.class)
public class TestClass {
  @Before
  public void setUp(){
    MockServiceFactory.initMockService();
    PowerMock.mockStatic(SomeClassWithStaticMethod.class);

    PowerMock.replayAll();

  }
 
  public void someTest(){
    //test impl
  }
}


Here the class for MockServiceFactory:

@PrepareForTest(ServiceFactroy.class)
public class MockServiceFactory{
  public static void initMockService(){
    ServiceFactory s = PowerMock.createMock(ServiceFactory.class); //ServiceFactory is the class I actually want to mock
    PowerMock.mockStatic(ServiceFactory.class);
    //some more code
  }
}

As you can see I want to call mockStatic in two different classes once in my Test and once in a Factory class that creates mock objects for ServiceFactory.
How can I make this code running? Because running it always results in:

java.lang.IllegalStateException: no last call on a mock available
    at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:520)
    at org.easymock.EasyMock.expect(EasyMock.java:498)
...

Thank you for your help!!!


--
You received this message because you are subscribed to the Google Groups "PowerMock" group.
To unsubscribe from this group and stop receiving emails from it, send an email to powermock+...@googlegroups.com.
To post to this group, send email to powe...@googlegroups.com.
Visit this group at http://groups.google.com/group/powermock?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Fabian

unread,
Feb 12, 2013, 9:42:10 AM2/12/13
to powe...@googlegroups.com
Oh yes, sorry, I forgot it here. Below the improved code snippet:


@RunWith(PowerMockRunner.class)
@PrepareForTest(SomeClassWithStaticMethod.class)
public class TestClass {
  @Before
  public void setUp(){
    MockServiceFactory.initMockService();
    PowerMock.mockStatic(SomeClassWithStaticMethod.class);

    EasyMock.expect(
SomeClassWithStaticMethod.someStaticMethod()).andReturn(PowerMock.createMock(SomeClassWithStaticMethod.class)
    P
owerMock.replayAll();

  }
 
  public void someTest(){
    //test impl
  }
}


@PrepareForTest(ServiceFactroy.class)
public class MockServiceFactory{
  public static void initMockService(){
    ServiceFactory s = PowerMock.createMock(ServiceFactory.class); //ServiceFactory is the class I actually want to mock
    PowerMock.mockStatic(ServiceFactory.class);
    EasyMock.expect(ServiceFactory.getInstance()).andReturn(s); //Here the is the IllegalStateException thrown
    //some more code
  }
}

Johan Haleby

unread,
Feb 12, 2013, 9:48:14 AM2/12/13
to powe...@googlegroups.com
Ok I get it now. How ever you must include the classes that you want to prepare for test at the same level as the "RunWith" annotation. PowerMock is using reflection of the class annotated with @RunWith to find which classes it should prepare. If you do:

@RunWith(PowerMockRunner.class)
@PrepareForTest({SomeClassWithStaticMethod.class, ServiceFactroy.class})

then I think it should work. If you have classes you want to prepare in many test cases consider creating a mock policy.

Regards,
/Johan

Fabian

unread,
Feb 12, 2013, 10:03:30 AM2/12/13
to powe...@googlegroups.com
Yes, if I put it on the same level (in the class TestClass), then it works. The goal of this is that I want to provide MockServiceFactory as a tool that can be easily used by other developers in order to write tests. The developers should not need to know that they have to add ServiceFactory.class to the @PrepareForTest annotation in the class TestClass. Do you understand what I mean?
Thanks for the link to mock policy. I will have a look at it.

Johan Haleby

unread,
Feb 12, 2013, 10:59:51 AM2/12/13
to powe...@googlegroups.com
In that case I recommend you to build a mock policy. With a mock policy you can prepare classes for test and mock some methods of certain classes etc.

Regards,
/Johan

Fabian

unread,
Feb 12, 2013, 11:21:28 AM2/12/13
to powe...@googlegroups.com
Ok, thank you very much for your help, Johan!

Best regards,
Fabian
Reply all
Reply to author
Forward
0 new messages