Java PowerMock PrepareForTest 注释导致 AmazonSQSClient 构造函数出现问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18385074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PowerMock PrepareForTest annotation causing problems with AmazonSQSClient constructor
提问by Sarah Tattersall
I'm having some trouble with the PrepareForTestannotation and creating a new instance of an AmazonSQSClient.
我在使用PrepareForTest注释和创建 AmazonSQSClient 的新实例时遇到了一些问题。
I'm writing a Jenkins plugin and unfortunately need to mock the FormValidationstatic class in order to ensure that warning and error messages are produced on field validation of my plugin. However when creating an instance of AmazonSQSClient
I get an org.apache.http.conn.ssl.SSLInitializationException
我正在编写一个 Jenkins 插件,不幸的是需要模拟FormValidation静态类,以确保在我的插件的字段验证时生成警告和错误消息。但是,当创建一个实例时,AmazonSQSClient
我得到一个org.apache.http.conn.ssl.SSLInitializationException
I've abstracted it down to a very simple example, here's my test file:
我把它抽象成一个非常简单的例子,这是我的测试文件:
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();
}
}
On running this code I get the following error:
在运行此代码时,我收到以下错误:
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.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.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
In order to help anyone wanting to build and run this quickly here is my pom.xml file:
为了帮助任何想要快速构建和运行它的人,这里是我的 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>
When the annotation @PrepareForTest(Foo.class)
is removed from the method the test runs fine.
@PrepareForTest(Foo.class)
从方法中删除注释后,测试运行良好。
I was wondering if someone could explain why this is happening and if there is a work around for it or a way to avoid mocking the FormValidation
class?
我想知道是否有人可以解释为什么会发生这种情况,是否有解决方法或避免嘲笑FormValidation
课程的方法?
Thanks.
谢谢。
回答by Natalie Hooper
Try to add @PowerMockIgnore("org.apache.http.conn.ssl.*")
annotation to your class
尝试@PowerMockIgnore("org.apache.http.conn.ssl.*")
为您的课程添加注释
回答by Marc
As @Natalie already mentioned, you can work with the @PowerMockIgnore()
annotation. Maybe you need to ignore the packages javax.net.ssl.*
and / or javax.crypto.*
:
正如@Natalie 已经提到的,您可以使用@PowerMockIgnore()
注释。也许您需要忽略包javax.net.ssl.*
和/或javax.crypto.*
:
@PowerMockIgnore({"org.apache.http.conn.ssl.*", "javax.net.ssl.*" , "javax.crypto.*"})
You can get here some background information:
您可以在此处获取一些背景信息:
https://groups.google.com/forum/#!topic/powermock/v4nreP2AnOQ
https://groups.google.com/forum/#!topic/powermock/v4nreP2AnOQ
This is most likely because SSLContext is loaded by the bootstrap classloader and PowerMock cannot byte-code manipulate these classes. You have to use this approach to mock that method. /Johan Haleby
这很可能是因为 SSLContext 是由引导类加载器加载的,而 PowerMock 无法对这些类进行字节码操作。您必须使用这种方法来模拟该方法。/约翰·哈勒比