PowerMock PrepareForTest注释导致AmazonSQSClient构造函数出现问题

我在使用PrepareForTest注释和创建AmazonSQSClient的新实例时遇到了一些麻烦。

我正在写一个Jenkins插件,不幸的是需要模拟FormValidation静态类,以确保在我的插件的字段validation时产生警告和错误消息。 但是在创建AmazonSQSClient的实例时,我得到一个org.apache.http.conn.ssl.SSLInitializationException

我把它抽象成一个非常简单的例子,这是我的测试文件:

 package com.test; import com.amazonaws.services.sqs.AmazonSQS; import com.amazonaws.services.sqs.AmazonSQSClient; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) public class SQSTest { // This is for mimicking the mocking of FormValidation private static class Foo {} @Test @PrepareForTest(Foo.class) public void buildTest() { AmazonSQS sqs = new AmazonSQSClient(); } } 

在运行此代码时,我收到以下错误:

 org.apache.http.conn.ssl.SSLInitializationException: Failure initializing default SSL context at org.apache.http.conn.ssl.SSLSocketFactory.createDefaultSSLContext(SSLSocketFactory.java:360) at org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory(SSLSocketFactory.java:175) at org.apache.http.impl.conn.SchemeRegistryFactory.createDefault(SchemeRegistryFactory.java:49) at org.apache.http.impl.conn.PoolingClientConnectionManager.(PoolingClientConnectionManager.java:93) at com.amazonaws.http.ConnectionManagerFactory.createPoolingClientConnManager(ConnectionManagerFactory.java:26) at com.amazonaws.http.HttpClientFactory.createHttpClient(HttpClientFactory.java:87) at com.amazonaws.http.AmazonHttpClient.(AmazonHttpClient.java:121) at com.amazonaws.AmazonWebServiceClient.(AmazonWebServiceClient.java:66) at com.amazonaws.services.sqs.AmazonSQSClient.(AmazonSQSClient.java:189) at com.amazonaws.services.sqs.AmazonSQSClient.(AmazonSQSClient.java:93) at com.test.SQSTest.buildTest(SQSTest.java:19) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310) at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:88) at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282) at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86) at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120) at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33) at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118) at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101) at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53) at org.junit.runner.JUnitCore.run(JUnitCore.java:160) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) Caused by: java.security.NoSuchAlgorithmException: class configured for KeyManagerFactory: sun.security.ssl.KeyManagerFactoryImpl$SunX509 not a KeyManagerFactory at sun.security.jca.GetInstance.checkSuperClass(GetInstance.java:258) at sun.security.jca.GetInstance.getInstance(GetInstance.java:237) at sun.security.jca.GetInstance.getInstance(GetInstance.java:164) at javax.net.ssl.KeyManagerFactory.getInstance(KeyManagerFactory.java:138) at org.apache.http.conn.ssl.SSLSocketFactory.createSSLContext(SSLSocketFactory.java:223) at org.apache.http.conn.ssl.SSLSocketFactory.createDefaultSSLContext(SSLSocketFactory.java:358) ... 42 more 

为了帮助任何想要快速构建和运行的人,请访问我的pom.xml文件:

  4.0.0 com.test test.sqs 1.0-SNAPSHOT hpi   1.96    com.amazonaws aws-java-sdk 1.5.4   junit junit 4.11   org.mockito mockito-all 1.9.5   org.powermock powermock-api-mockito 1.5.1   org.powermock powermock-module-junit4 1.5.1    

从方法中删除注释@PrepareForTest(Foo.class) ,测试运行正常。

我想知道是否有人可以解释为什么会发生这种情况,是否有解决方法或避免FormValidation类的方法?

谢谢。

尝试将@PowerMockIgnore("org.apache.http.conn.ssl.*")注释添加到您的class级

正如@Natalie已经提到的,你可以使用@PowerMockIgnore()注释。 也许你需要忽略包javax.net.ssl.*和/或javax.crypto.*

 @PowerMockIgnore({"org.apache.http.conn.ssl.*", "javax.net.ssl.*" , "javax.crypto.*"}) 

你可以在这里获得一些背景信息:

https://groups.google.com/forum/#!topic/powermock/v4nreP2AnOQ

这很可能是因为SSLContext是由引导类加载器加载的,而PowerMock不能对这些类进行字节代码操作。 您必须使用此方法来模拟该方法。 / Johan Haleby