Аннотации PowerMock PrepareForTest, вызывающие проблемы с конструктором AmazonSQSClient

У меня возникают проблемы с аннотацией PrepareForTest и созданием нового экземпляра AmazonSQSClient.

Я пишу плагин Jenkins и, к сожалению, нужно издеваться над статическим классом FormValidation, чтобы гарантировать, что предупреждения и сообщения об ошибках созданный при проверке поля моего плагина. Однако при создании экземпляра 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.<init>(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.<init>(AmazonHttpClient.java:121)
 at com.amazonaws.AmazonWebServiceClient.<init>(AmazonWebServiceClient.java:66)
 at com.amazonaws.services.sqs.AmazonSQSClient.<init>(AmazonSQSClient.java:189)
 at com.amazonaws.services.sqs.AmazonSQSClient.<init>(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
</init></init></init></init></init>

Чтобы помочь всем, кто хочет построить и запустить это быстро, вот мой файл pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelversion>4.0.0</modelversion>
 <groupid>com.test</groupid>
 <artifactid>test.sqs</artifactid>
 <version>1.0-SNAPSHOT</version>
 <packaging>hpi</packaging>
 <properties>
 <!--
 explicitly specifying the latest version here because one we get from the parent POM
 tends to lag behind a bit
 -->
 <maven-hpi-plugin.version>1.96</maven-hpi-plugin.version>
 </properties>
 <dependencies>
 <dependency>
 <groupid>com.amazonaws</groupid>
 <artifactid>aws-java-sdk</artifactid>
 <version>1.5.4</version>
 </dependency>
 <dependency>
 <groupid>junit</groupid>
 <artifactid>junit</artifactid>
 <version>4.11</version>
 </dependency>
 <dependency>
 <groupid>org.mockito</groupid>
 <artifactid>mockito-all</artifactid>
 <version>1.9.5</version>
 </dependency>
 <dependency>
 <groupid>org.powermock</groupid>
 <artifactid>powermock-api-mockito</artifactid>
 <version>1.5.1</version>
 </dependency>
 <dependency>
 <groupid>org.powermock</groupid>
 <artifactid>powermock-module-junit4</artifactid>
 <version>1.5.1</version>
 </dependency>
 </dependencies>
</project>

Когда аннотация @PrepareForTest(Foo.class) удаляется из метода, тест проходит нормально.

Мне было интересно, может ли кто-нибудь объяснить, почему это происходит, и если для этого есть работа или способ избежать издевательств над классом FormValidation?

Спасибо.

2 ответа

Попробуйте добавить аннотацию @PowerMockIgnore("org.apache.http.conn.ssl.*") к вашему классу


Как уже упоминалось в @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 загружается загрузчиком классов bootstrap, а PowerMock не может управлять байтовым кодом этими классами. Вы должны использовать этот подход для издевательства над этим методом.   /Йохан Халеби

licensed under cc by-sa 3.0 with attribution.