Getting IllegalArgumentException with JavaAssist:PowerMock+TestNG+Mockito

1,122 views
Skip to first unread message

Karthik Krishnan

unread,
Jan 8, 2010, 8:06:53 PM1/8/10
to PowerMock
Hi PowerMock gurus,

I am a powermock newbie writing my first TestNG test class. I have a
static class that just returns true if a String argument
equalsIgnoreCase "John" and I am calling that from TestNG test class.
I am mocking with Mockito 1.8x. I have use these blog posts and sample
code as as tutorial examples.
1.
http://code.google.com/p/powermock/source/browse/trunk/modules/module-test/powermock/testng-test/src/test/java/samples/testng/MockStaticExtendsPowerMockTestCaseTest.java
2. http://blog.jayway.com/2009/10/28/untestable-code-with-mockito-and-powermock/
3. http://blog.jayway.com/2009/12/14/powermock-testng-true/

I am not sure what I am doing wrong. Any advice would be appreciated.

Stack Trace

java.lang.IllegalArgumentException:
PowerMockDemoTest_$$_javassist_0@32e003
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke
(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:
607)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:517)
........


Code
---------
public class Static {
public static boolean isEqualToJohn(String name) {
return name != null && name.equalsIgnoreCase("John") ? true : false;
}
}

Test Class
---------------
@PrepareForTest(Static.class)
public class PowerMockDemoTest {

@Test
public void testWithoutDataProvider() throws Exception {
Name john = new Name("abc");
PowerMockito.mockStatic(Static.class);
Mockito.when(Static.isEqualToJohn(Mockito.anyString())).thenReturn
(true);
Assert.assertEquals(Static.isEqualToJohn("abc"), true);
PowerMockito.verifyStatic();
}

private class Name {

private final String name;

public Name(String name) {
this.name = name;
}

public int isNameEqualToJohn() {
boolean flag = Static.isEqualToJohn(name);
return flag ? 1 : 0;
}

}
}

TestSuite:
<suite name="test" verbose="10" object-
factory="org.powermock.modules.testng.PowerMockObjectFactory">
<test name = "demo">
<classes>
<class name = "PowerMockDemoTest"/>
</classes>
</test>
</suite>

Johan Haleby

unread,
Jan 9, 2010, 6:02:46 AM1/9/10
to powe...@googlegroups.com
Hi,

It might be because you're missing the actual verification when you're verifying the static method? It should probably be something like:

PowerMockito.verifyStatic();
Static.isEqualToJohn("abc");

Verifying a static method is (unfortunately)  a two step process. You could try that and see if it makes any difference. You could also try extending PowerMockTestCase and see if you get the same error message (or perhaps you get a better one).

/Johan
PS: "Name" doesn't do anything in your example above?

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




Kartik Kumar

unread,
Jan 11, 2010, 7:59:23 PM1/11/10
to powe...@googlegroups.com
Hi Johan,
As you suggested, I executed PowerMockito.verifyStatic() before calling. My modified code is as follows (only test method). Rest remains unchanged.


@Test
    public void testWithoutDataProvider() throws Exception {
        //Name john = new Name("abc");
        PowerMockito.mockStatic(Static.class);
        Mockito.when(Static.isEqualToJohn(Mockito.anyString()))
            .thenReturn(Mockito.eq(true));
        PowerMockito.verifyStatic();
        boolean flag = Static.isEqualToJohn("abc");
        Assert.assertTrue(flag);
    }

java.lang.IllegalArgumentException: com.wellsfargo.examples.powermock.testng.PowerMockDemoTest_$$_javassist_0@330f47
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:607)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:517)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:669)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:956)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:110)
    at org.testng.TestRunner.runWorkers(TestRunner.java:759)
    at org.testng.TestRunner.privateRun(TestRunner.java:592)
    at org.testng.TestRunner.run(TestRunner.java:486)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:332)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:327)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:299)
    at org.testng.SuiteRunner.run(SuiteRunner.java:204)
    at org.testng.TestNG.createAndRunSuiteRunners(TestNG.java:877)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:842)
    at org.testng.TestNG.run(TestNG.java:751)
    at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:73)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:124)


I will try this on JUnit 4.x and let you how it goes.

Name is a bean that takes a string as a constructor argument. I had it in the test but removed it to simply the test even further.

Kartik Kumar

unread,
Jan 11, 2010, 9:00:31 PM1/11/10
to powe...@googlegroups.com
So I wrote two tests classes, once in JUnit4 and the other in TestNG. In both tests, one test method only uses Mockito, the other leverages PowerMock and Mockito. When I try to run JUnit 4 test with PowerMock for mocking static method, it fails with the error message given below. But TestNG tests return the same error message.

JUnit4 Test Class
-------------------------
@RunWith(PowerMockRunner.class)
@PrepareForTest(value = {Static.class})
public class PowerMockDemoJUnit4Test {
   
   
    /** SUCCESSFUL TEST. */
    @Test
    public void testWithOnlyMockito() {
        Name name = Mockito.mock(Name.class);
        Mockito.when(name.isEqualToJohn(Mockito.anyString())).thenReturn(true);
        Assert.assertTrue(name.isEqualToJohn("abc"));       
    }
   
    /** FAILD TEST. */
    @Test
    public void testWithPowerMockStatic() throws Exception {
        PowerMockito.mockStatic(Static.class);
        Mockito.when(Static.isEqualToJohn(Mockito.anyString())).thenReturn(true);
        PowerMockito.verifyStatic();
        Static.isEqualToJohn("abc");
    }
   
    public class Name {
        public boolean isEqualToJohn(String str) {
            return Static.isEqualToJohn(str);
        }
    }
}

Failure Stack Trace
----------------------------
org.powermock.reflect.exceptions.TooManyFieldsFoundException: Two or more fields matching type java.lang.String.
    at org.powermock.reflect.internal.WhiteboxImpl.findSingleFieldUsingStrategy(WhiteboxImpl.java:458)
    at org.powermock.reflect.internal.WhiteboxImpl.findFieldInHierarchy(WhiteboxImpl.java:442)
    at org.powermock.reflect.internal.WhiteboxImpl.setInternalState(WhiteboxImpl.java:339)
    at org.powermock.reflect.Whitebox.setInternalState(Whitebox.java:206)
    at org.powermock.api.mockito.internal.invocationcontrol.InvocationControlAssertionError.updateErrorMessageForMethodInvocation(InvocationControlAssertionError.java:74)
    at org.powermock.api.mockito.internal.invocationcontrol.MockitoMethodInvocationControl.performIntercept(MockitoMethodInvocationControl.java:240)
    at org.powermock.api.mockito.internal.invocationcontrol.MockitoMethodInvocationControl.invoke(MockitoMethodInvocationControl.java:144)
    at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:98)
    at org.powermock.core.MockGateway.methodCall(MockGateway.java:53)
    at com.wellsfargo.examples.powermock.testng.Static.isEqualToJohn(Static.java:6)
    at com.wellsfargo.examples.powermock.testng.PowerMockDemoJUnit4Test.testWithPowerMockStatic(PowerMockDemoJUnit4Test.java:29)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:322)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:309)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:297)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:222)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:161)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:135)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:133)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:112)
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:55)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)



TestNG Test
-----------------

   @PrepareForTest(value = {Static.class})
public class PowerMockTestNGTest {
   
   /** FAILED */

    @Test
    public void testWithoutDataProvider() throws Exception {
        PowerMockito.mockStatic(Static.class);
        Mockito.when(Static.isEqualToJohn(Mockito.anyString()))
            .thenReturn(Mockito.eq(true));
        PowerMockito.verifyStatic();
        boolean flag = Static.isEqualToJohn("abc");
        Assert.assertTrue(flag);
    }
   
    /** FAILED */
    @Test
    public void testWithOnlyMockito() {
        Name name = Mockito.mock(Name.class);
        Mockito.when(name.isEqualToJohn(Mockito.anyString())).thenReturn(true);
        Assert.assertTrue(name.isEqualToJohn("abc"));       
    }

    public class Name {
        public boolean isEqualToJohn(String str) {
            return Static.isEqualToJohn(str);
        }
    }
}

Stack Trace (Same for both test methods)
-------------------------------------------------------------
java.lang.IllegalArgumentException: com.wellsfargo.examples.powermock.testng.PowerMockTestNGTest _$$_javassist_0@335fa0

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:607)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:517)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:669)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:956)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:110)
    at org.testng.TestRunner.runWorkers(TestRunner.java:759)
    at org.testng.TestRunner.privateRun(TestRunner.java:592)
    at org.testng.TestRunner.run(TestRunner.java:486)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:332)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:327)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:299)
    at org.testng.SuiteRunner.run(SuiteRunner.java:204)
    at org.testng.TestNG.createAndRunSuiteRunners(TestNG.java:877)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:842)
    at org.testng.TestNG.run(TestNG.java:751)
    at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:73)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:124)




Johan Haleby

unread,
Jan 12, 2010, 3:12:48 AM1/12/10
to powe...@googlegroups.com
Great description! Do you have these things checked in somewhere? Or could you upload the code to the google group? I'll try to look at it later this evening.

/Johan

Kartik Kumar

unread,
Jan 12, 2010, 12:46:52 PM1/12/10
to powe...@googlegroups.com
Hi Johan,

Thanks for taking a look at this. I am attaching all files for your perusal.

Thanks,

Kartik
PowerMockDemoJUnit4Test.java
PowerMockDemoTestNGTest.java
Static.java
powermock-testng.xml

Johan Haleby

unread,
Jan 12, 2010, 1:44:33 PM1/12/10
to powe...@googlegroups.com
Hi,

Thanks for the files but next time please go to our google group and upload the files there instead of attaching them to the mail.

Anyway in the JUnit test the problems is that you're not actually testing anything. You're only verifying. The code should probably look something like:

@Test
public void testWithPowerMockStatic() throws Exception {
// Given
PowerMockito.mockStatic(Static.class);
Mockito.when(Static.isEqualToJohn(Mockito.anyString())).thenReturn(true);

// Invoke the actual test
Static.isEqualToJohn("abc");
// (Optionally) verify that static method isEqualToJohn was called with parameter "abc"
PowerMockito.verifyStatic();
Static.isEqualToJohn("abc");
}

In TestNG I get this exception when I look at the index.html file generated by TestNG:
java.lang.reflect.InvocationTargetException at org.powermock.modules.testng.internal.PowerMockTestNGMethodHandler.invoke(PowerMockTestNGMethodHandler.java:48) at org.test.PowerMockDemoTestNGTest_$$_javassist_0.testWithoutDataProvider(PowerMockDemoTestNGTest_$$_javassist_0.java) at org.test.PowerMockDemoTestNGTest.main(PowerMockDemoTestNGTest.java:23) Caused by:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Misplaced argument matcher detected here: at org.test.PowerMockDemoTestNGTest.testWithoutDataProvider(PowerMockDemoTestNGTest.java:29)

You cannot use argument matchers outside of verification or stubbing. Examples of correct usage of argument matchers: when(mock.get(anyInt())).thenReturn(null); doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject()); verify(mock).someMethod(contains("foo")) Also, this error might show up because you use argument matchers with methods that cannot be mocked. Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode() methods. at 

org.powermock.api.mockito.PowerMockito.verifyStatic(PowerMockito.java:155) at org.powermock.api.mockito.PowerMockito.verifyStatic(PowerMockito.java:129) at org.test.PowerMockDemoTestNGTest.testWithoutDataProvider(PowerMockDemoTestNGTest.java:31) at org.test.PowerMockDemoTestNGTest_$$_javassist_0._d3testWithoutDataProvider(PowerMockDemoTestNGTest_$$_javassist_0.java) ... 27 more 

There are two problems in your test. First of all you cannot use matchers in "thenReturn" and that's what's causing the exception above (please read the Mockito documentation). Secondly you made the same error when verifying the static method. The test should look something like this:

@Test
public void testWithoutDataProvider() throws Exception {
PowerMockito.mockStatic(Static.class);
Mockito.when(Static.isEqualToJohn(Mockito.anyString())).thenReturn(true);

boolean flag = Static.isEqualToJohn("abc");
Assert.assertTrue(flag);
PowerMockito.verifyStatic();
Static.isEqualToJohn("abc");
}


/Johan

Karthik Krishnan

unread,
Jan 12, 2010, 5:02:01 PM1/12/10
to PowerMock
Hi Johan,

Thanks for the quick reply. My JUnit4 tests run successfully now.
When I try to run my TestNG tests with Eclipse plugin, my Mockito
without Powermock test passes but Powermock with Mockito fails, even
after copying your code in TestNG. When I try to run TestNG test using
Eclipse TestNG plugin (latest one available), then I get the same
error. My TestNG test code using PowerMock

@Test
public void testWithoutDataProvider() throws Exception {
PowerMockito.mockStatic(Static.class);
Mockito.when(Static.isEqualToJohn(Mockito.anyString())).thenReturn
(true);

Assert.assertTrue(Static.isEqualToJohn("abc"));
PowerMockito.verifyStatic();
Static.isEqualToJohn("abc");
}

But this is expected as you clearly mention in this blog (http://
blog.jayway.com/2009/12/14/powermock-testng-true/) that if you don't
specify the object factory in your test suite, PowerMock functionality
does not get picked up and the tests fail.

When I try to run my test suite xml, both tests fail with
IllegalArgumentException with the error message. I tried to see if
this is an isolated incident (I disabled above test by setting @Test
(enabled = false), then running the TestNG test with eclipse plugin.
Tests not dependant upon power mock run successfully with Eclipse
plugin but fail when using running with test suite that defines
PowerMockObjectFactory.

This may sound like a stupid question but have I missed something
here?
Thanks,

Kartik

On Jan 12, 10:44 am, Johan Haleby <johan.hal...@gmail.com> wrote:
> Hi,
>
> Thanks for the files but next time please go to our google

> group<http://groups.google.com/group/powermock>and upload the files

> On Tue, Jan 12, 2010 at 6:46 PM, Kartik Kumar <krishnan.1...@gmail.com>wrote:
>
> > Hi Johan,
>
> > Thanks for taking a look at this. I am attaching all files for your
> > perusal.
>
> > Thanks,
>
> > Kartik
>

> > On Tue, Jan 12, 2010 at 12:12 AM, Johan Haleby <johan.hal...@gmail.com>wrote:
>
> >> Great description! Do you have these things checked in somewhere? Or could
> >> you upload the code to the google group? I'll try to look at it later this
> >> evening.
>
> >> /Johan
>

> ...
>
> read more »

Johan Haleby

unread,
Jan 13, 2010, 2:11:47 AM1/13/10
to powe...@googlegroups.com
Hi,

I can't really tell what you're missing, after the changes I told you about in my previous mail both tests pass on my computer (or are you referring to your "real" test cases now?). I'm not sure that the Eclipse plugin works with objectfactories/powermock (perhaps you could ask this question on the testng mailing list, I'm also interested to know) I always execute the tests from Maven or using something like this from within Eclipse:

 public static void main(String[] args) {
     TestNG tng = new TestNG();
     tng.setTestSuites(Arrays.asList("/path/to/suite.xml"));
     tng.setVerbose(10);
     tng.run();
   }

Just to be sure, are you using the latest version of TestNG (5.11)? PowerMock will not work on any previous version of TestNG.

/Johan

Kartik Kumar

unread,
Jan 13, 2010, 12:46:10 PM1/13/10
to powe...@googlegroups.com
Hi Johan,

I am using TestNG v5.11 and the latest Eclipse plugin I downloaded from this link (http://testng.org/doc/download.html). You can run testsuite xml by
1. Selecting TestSuite.xml
2. Right Click -> Run as -> TestNG Test

I will try your code snippet as well and will let you know it goes.

Thanks,

Kartik

Johan Haleby

unread,
Jan 14, 2010, 1:54:55 AM1/14/10
to powe...@googlegroups.com
Please do so. Thanks for the tip about the eclipse plugin, I'll try it out.

Kartik Kumar

unread,
Jan 15, 2010, 7:26:19 PM1/15/10
to powe...@googlegroups.com
Hi Johan,

Your code snippet executes my tests perfectly.

Thanks for your help.

Kartik
Reply all
Reply to author
Forward
0 new messages