Setting private static field with PowerMock 1.4 and Mockito 1.8.5 doesn't seem to work for me...

9,480 views
Skip to first unread message

Christian Balzer

unread,
Aug 5, 2013, 8:13:43 AM8/5/13
to powe...@googlegroups.com
Hi everyone,

I hope I'm posting this to the right mailing list (despite the error message below).
I have difficulties setting a private static field in a class for one of my tests. Here is the class under test; the test is just below it.

import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
//...

public class MyService extends ServiceUtils {
private static PoolingClientConnectionManager connectionManager;
private static DefaultHttpClient httpClient;
private ServiceLog log;
//...
public void doDestroy() throws ServiceException {
log.logDebug("Shutting down Connection Manager...");
try {
httpClient.getConnectionManager().shutdown();
} catch (Exception e) {
// catch any exception, format it, and pass it up.
throw new ServiceException(ErrorWrapper.formatException(e), e);
}
log.logInformation("Done.");
}
}

Now I want to test if the shutdown() method is actually called:
public class MyServiceTest {

@Test
public final void test_doDestroy() throws ServiceException {
  // variables
  PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
  PoolingClientConnectionManager spyConnectionManager = spy(connectionManager);
  DefaultHttpClient httpClient = new DefaultHttpClient(spyConnectionManager);
  MyService myService = new MyService();
// start setup mocks
ServiceLog mockedLog = mock(ServiceLog.class);
// end setup mocks
// start setup behaviour
Whitebox.setInternalState(myService, "log", mockedLog); 
Whitebox.setInternalState(MyService.class, "httpClient", httpClient);
// end setup behaviour
// act
stuboService.doDestroy();

// verify
verify(spyConnectionManager, times(1)).shutdown();
verify(mockedLog, times(1)).logDebug(anyString());
verify(mockedLog, times(1)).logInformation(anyString());
}
}
The above returns "java.lang.RuntimeException: Unable to set internal state on a private field. Please report to mockito mailing list." for the bold line.

If I change the first line to
@RunWith(PowerMockRunner.class)
@PrepareForTest({MyService.class})
public class MyServiceTest
I get the following "org.apache.http.conn.ssl.SSLInitializationException: class configured for SSLContext: com.sun.net.ssl.internal.ssl.SSLContextImpl not a SSLContext" (not sure what that means).

But if I remove those two lines again and then go on and change the bold line to the following:
 Whitebox.setInternalState(myService, "httpClient", httpClient);
the test passes - which is great, but I don't quite understand why.

I thought I had to use Whitebox.setInternalState() to set a private field, that passing in "xyz.class" would allow me to set a private static field and that I would not need to add the @RunWith and @PrepareForTest annotations if I just wanted to use PowerMock's Whitebox (and otherwise rely on Mockito). Can anyone help me, please?

Kind regards,

Christian
 

Johan Haleby

unread,
Aug 5, 2013, 9:30:14 AM8/5/13
to powe...@googlegroups.com
Hi, 

What minor version of PowerMock 1.4 are you using?

/Johan


--
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.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Christian Balzer

unread,
Aug 5, 2013, 11:36:46 AM8/5/13
to powe...@googlegroups.com
Hi Johan,

We use Maven to include PowerMock, and the version in the POM file is just 1.4, so I assume it's 1.4.0:
      <dependency>
         <groupId>org.powermock.api</groupId>
         <artifactId>powermock-api-mockito</artifactId>
         <version>1.4</version>
         <scope>test</scope>
      </dependency>

The md5 hash is f96af7c1d77d5ac3a646a19ebbf9277b, according to our Nexus. Does that help?

Best regards,

Christian

Christian Balzer

unread,
Aug 6, 2013, 9:46:09 AM8/6/13
to powe...@googlegroups.com
Hi all,

so, adding the following works:
@RunWith(PowerMockRunner.class)
@PrepareOnlyThisForTest({MyService.class})
@PowerMockIgnore( "org.apache.http.conn.ssl.*" )

but the underlying question remains, of course:
I thought I had to use Whitebox.setInternalState() to set a private field, that passing in xyz.class would allow me to set a private static field. Why do I need to pass an object in to set a static field?

Best regards,

Christian

Johan Haleby

unread,
Aug 7, 2013, 3:33:55 PM8/7/13
to powe...@googlegroups.com
Hi, 

I'm on vacation right not but I'll look into your questions when I'm back home. Hope that's alright.

Regards,
/Johan

Johan Haleby

unread,
Aug 19, 2013, 2:30:59 AM8/19/13
to powe...@googlegroups.com
Hmm I don't really know why you experience the exception that you see. It seems to me that you're using the Whitebox API correctly. I could probably look into it a bit if you provide a sample project otherwise it's really hard :/
Reply all
Reply to author
Forward
0 new messages