Re: [powermock] Powermock no last call on a mock available

4,872 views
Skip to first unread message

Johan Haleby

unread,
Feb 21, 2013, 2:37:37 AM2/21/13
to powe...@googlegroups.com
I accidentally replied to the wrong e-mail so I don't know if you got the answer. Anyway I'll re-post it:

"You are mixing PowerMockito and EasyMock! You should use the PowerMock class and not PowerMockito when working with EasyMock.

Regards,
/Johan"

On Wed, Feb 20, 2013 at 10:03 PM, powder366 <jonas....@gmail.com> wrote:
Running the code from:http://www.jayway.com/2009/05/17/mocking-static-methods-in-java-system-classes/

I get the following error:

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)
at ff.MockStaticExampleTest.mockStaticExample(MockStaticExampleTest.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

With the code:

package ff;
import static org.junit.Assert.assertEquals;
import org.easymock.EasyMock;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Greeter.class)
public class MockStaticExampleTest {
  @Test
  public void mockStaticExample() throws Exception {

  String expectedGreeting = "greeting";
  String nameToGreet = "name";

  PowerMockito.mockStatic(Greeter.class);

  EasyMock.expect(Greeter.getGreeting(nameToGreet)).andReturn(expectedGreeting);

  PowerMock.replayAll();

  String actualGreeting = Greeter.getGreeting(nameToGreet);

  PowerMock.verifyAll();

  assertEquals("Expected and actual greeting did not match ", expectedGreeting, actualGreeting);

  }
}

Anyone seen this? Thanks!

--
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.
 
 

powder366

unread,
Feb 21, 2013, 4:23:47 AM2/21/13
to powe...@googlegroups.com
That did! Thank you very much...

powder366

unread,
Feb 21, 2013, 7:25:31 AM2/21/13
to powe...@googlegroups.com
Moving this into an Android unit test project it does not run, just exits:

Im trying to mock static methods, as I understand Mockito does not do it? Im now trying PowerMock with the error above in an Android unit test project.


With Android how should I mock static methods? Mockito, PowerMock or?

Johan Haleby

unread,
Feb 21, 2013, 7:30:44 AM2/21/13
to powe...@googlegroups.com
You should probably be looking at https://code.google.com/p/powermock/wiki/MockitoUsage13 which is the new documentation. Wether or not you're going to use PowerMock or PowerMockito depends on if you want to work with EasyMock or Mockito. The example you just gave where using EasyMock syntax.

Regards
/Johan

powder366

unread,
Feb 21, 2013, 8:33:38 AM2/21/13
to powe...@googlegroups.com
1. Running my non-static Mockito test case with the following libraries in libs (not added to my Java Build Path/Libraries in Eclipse):

dexmaker-1.0.jar
dexmaker-mockito-1.0.jar
mockito-all-1.9.5.jar

Everything works (starting it with "Android JUnit Test"). Code:

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import junit.framework.Assert;
import android.content.Context;
import android.test.InstrumentationTestCase;

public class PreferenceTest extends InstrumentationTestCase {

public void testCountry() {
Utilities mockTab = mock(Utilities.class);
Context contextMock = mock(Context.class);

// No static calls
when(mockTab.setWeekConfiguration(contextMock.getApplicationContext())).thenReturn(true);

boolean isValid = mockTab.setWeekConfiguration(contextMock.getApplicationContext());

Assert.assertTrue(isValid);
isValid = mockTab.setWeekConfiguration(contextMock.getApplicationContext());
Assert.assertTrue(isValid);
}
}

2. Now trying out https://code.google.com/p/powermock/wiki/MockitoUsage13 and sample "A full example for mocking, stubbing & verifying static method". I add the following libraries in lib:

cglib-nodep-2.2.jar
dexmaker-1.0.jar
dexmaker-mockito-1.0.jar
javassist-3.17.1-GA.jar
junit-4.8.2.jar
mockito-all-1.9.5.jar
objenesis-1.2.jar
powermock-mockito-1.5-full.jar

3. My first Mockito non-static test case break with the error:

[2013-02-21 14:15:23 - TimesheetTest] Dx warning: Ignoring InnerClasses attribute for an anonymous inner class
(net.sf.cglib.util.StringSwitcher$Generator$1) that doesn't come with an
associated EnclosingMethod attribute. This class was probably produced by a
compiler that did not target the modern .class file format. The recommended
solution is to recompile the class from source, using an up-to-date compiler
and without specifying any "-target" type options. The consequence of ignoring
this warning is that reflective operations on this class will incorrectly
indicate that it is *not* an inner class.
[2013-02-21 14:15:25 - Dex Loader] Unable to execute dex: Multiple dex files define Lorg/hamcrest/Description;
[2013-02-21 14:15:25 - TimesheetTest] Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lorg/hamcrest/Description;

4. Trying out the new testcase, call classCallStaticMethodObj.execute(); is not found?

5. Commenting out  the call classCallStaticMethodObj.execute(); Running the static one I get the error:

[2013-02-21 14:20:08 - TimesheetTest] Dx warning: Ignoring InnerClasses attribute for an anonymous inner class
(net.sf.cglib.util.StringSwitcher$Generator$1) that doesn't come with an
associated EnclosingMethod attribute. This class was probably produced by a
compiler that did not target the modern .class file format. The recommended
solution is to recompile the class from source, using an up-to-date compiler
and without specifying any "-target" type options. The consequence of ignoring
this warning is that reflective operations on this class will incorrectly
indicate that it is *not* an inner class.
[2013-02-21 14:20:09 - Dex Loader] Unable to execute dex: Multiple dex files define Lorg/hamcrest/Description;
[2013-02-21 14:20:09 - TimesheetTest] Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lorg/hamcrest/Description;

6. The code is:

import static org.mockito.Mockito.mock;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import android.content.Context;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Utilities.class)
public class PreferenceTest {

@Test
public void testMethodThatCallsStaticMethod() {

Context contextMock = mock(Context.class); // Is this possble?
PowerMockito.mockStatic(Utilities.class);

Mockito.when(Utilities.setWeekConfiguration(contextMock.getApplicationContext())).thenReturn(true);

// Does not find classCallStaticMethodObj?
classCallStaticMethodObj.execute();

PowerMockito.verifyStatic(Mockito.times(1));

Utilities.setWeekConfiguration(contextMock.getApplicationContext());
}

}

7. My question: How can I configure Mockito and Powermock in an Android Test Project with the examples?

Johan Haleby

unread,
Feb 21, 2013, 10:40:48 AM2/21/13
to powe...@googlegroups.com
Are you trying to run your tests on a physical Android device?!

Regards,
/Johan

powder366

unread,
Feb 21, 2013, 1:13:26 PM2/21/13
to powe...@googlegroups.com
Yes (point 1 worked).

powder366

unread,
Feb 21, 2013, 1:56:33 PM2/21/13
to powe...@googlegroups.com
I do this currently:

1. public class UtilitiesTest extends AndroidTestCase (Android way in emulator/phone)
2. public class ReleaseTest extends TestCase (standard JUnit)
3. public class OvertimeWeekTest extends ActivityInstrumentationTestCase2<Tab> (Robotium)
4. public class PreferenceTest extends InstrumentationTestCase (Mockito, just started with a small test)

And my next step was to mock static and privates as well and I noticed it did not work for my four cases above (as I understand it).
So I started to look on Mockito and PowerMock and then it started to get complicated:-) There are a lot of mocking frameworks out there, and Im not sure if Mockito and PowerMock 
is supported for Android. Got the feeling that Mockito does with dexmaker and PowerMock not?

So if you could clarify a bit it would be really helpful. I guess when I mock static and private I could do some part without running it in an emulator/phone.
Some parts must run in a emulator/phone. Is there a difference between emulator and phone and can I do it at all?

This was my first thing I stumbled on (it's located in static method):

TelephonyManager tm  = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

String loc = tm.getSimCountryIso().toLowerCase();

I wanted to mock getSimCountryIso() to deliver different values for my test.

Regards Jonas

Johan Haleby

unread,
Feb 21, 2013, 2:13:02 PM2/21/13
to powe...@googlegroups.com
PowerMock relies on byte-code manipulation and will not work when running on a physical Android device. You can test your Android code with PowerMock if you run your tests in Eclipse/Intellij. 

Regards,
/Johan
Message has been deleted

powder366

unread,
Feb 21, 2013, 5:50:04 PM2/21/13
to powe...@googlegroups.com
Thanks!, by the way I think your documentation for Mockito and PowerMock needs a cleanup. It's to cluttered and hard to understand (at least for me:-)). Maybe add some notes about Android too.
I found this link:

Johan Haleby

unread,
Feb 22, 2013, 1:08:54 AM2/22/13
to powe...@googlegroups.com
Please help out by improving the documentation. I'll be glad to add any changes.

Regards,
/Johan

Vladimir Bokan

unread,
Dec 24, 2013, 4:03:39 PM12/24/13
to powe...@googlegroups.com
Hi Jonas,

I encountered very similar situation while trying to pair up PowerMock and Mockito for mocking/stubbing final/static/private stuff for Android, mostly Bluetooth part of API. I guess Powermock doesn't work with DexMaker so this is not quite possible.

Did you ever suceed with this on real device/emulator or, as Johan mentioned, pure jUnit testing within Eclipse or command line?

I'm trying to emulate Bluetooth device connection and data transfers as much realistic as possible but whole thing with final classes is making it quite difficult, if not impossible.


Cheers,

Vladimir
Reply all
Reply to author
Forward
0 new messages