我使用的是以下版本的powermock和junit和javaassist。大多数测试用例都工作得很好,只有少数测试用例是为使用CloseableHttpClient的类编写的。我尝试过powermock + javaassist的不同组合,但似乎都不起作用。我的项目是遗留的,因此不使用maven。
javassist-3.24.0-GA
powermock-api-mockito-1.6.2
powermock-mockito-release-full-1.6.4-full
powermock-module-junit4-1.7.4
powermock-module-testng-1.6.6
junit-4.12.jar代码-
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.rmi.registry.Registry;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.http.HttpEntity;
import org.apache.http.StatusLine;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import com.yantra.yfc.log.YFCLogCategory;
import com.yantra.yfs.core.YFSSystem;
import com.yantra.yfs.japi.YFSEnvironment;
import com.yantra.yfs.japi.YFSUserExitException;
@RunWith(PowerMockRunner.class)
@PrepareForTest({HttpClientBuilder.class, PoolingHttpClientConnectionManager.class,Registry.class})
@PowerMockIgnore({"javax.management.*", "org.apache.http.conn.ssl.*", "com.amazonaws.*", "javax.net.ssl.*","com.sun.*"})
@SuppressStaticInitializationFor({ "com.yantra.yfs.core.YFSSystem" , "org.apache.http.client.config.RequestConfig",
"org.apache.http.conn.ssl.SSLConnectionSocketFactory", "org.apache.http.impl.client.HttpClients","org.apache.http.impl.client.HttpClientBuilder","org.apache.http.config.Registry","org.apache.http.config.RegistryBuilder","org.apache.http.HttpEntity"})
public class ConfirmRefundDistributionUETest extends PowerMockTestCase{
private ConfirmRefundDistributionUE confirmRefundDistributionUE;
private YFSEnvironment yfsEnvironment;
private YFCLogCategory yfc;
ConfirmRefundDistributionUEYIFAPI mockYIFApi;
CloseableHttpClient client ;
CloseableHttpResponse response;
HttpClientBuilder httpClientBuilder ;
RequestConfig defaultRequestConfig;
Builder customBuilder ;
PoolingHttpClientConnectionManager poolManager;
Registry rgt ;
org.apache.http.config.Registry registry;
RegistryBuilder rb ;
StatusLine sl;
HttpEntity he;
@BeforeMethod
public void beforeMethod() throws Exception {
PowerMockito.mockStatic(SSLConnectionSocketFactory.class);
PowerMockito.mockStatic(RequestConfig.class);
PowerMockito.mockStatic(HttpClients.class);
PowerMockito.mockStatic(RegistryBuilder.class);
PowerMockito.mockStatic(PlainConnectionSocketFactory.class);
PowerMockito.mockStatic(HttpClientBuilder.class);
client = PowerMockito.mock(CloseableHttpClient.class);
httpClientBuilder = PowerMockito.mock(HttpClientBuilder.class);
PowerMockito.when(HttpClients.custom()).thenReturn(httpClientBuilder);
Mockito.when(httpClientBuilder.setConnectionManager(anyObject())).thenReturn(httpClientBuilder);
PowerMockito.when(httpClientBuilder.setDefaultRequestConfig(Matchers.anyObject())).thenReturn(httpClientBuilder);
PowerMockito.when(httpClientBuilder.setProxy(Matchers.anyObject())).thenReturn(httpClientBuilder);
PowerMockito.when(httpClientBuilder.build()).thenReturn(client);
PowerMockito.when(client.execute(anyObject())).thenReturn(response);
PowerMockito.when(response.getStatusLine()).thenReturn(sl);
}
@Test
public void confirmRefundDistribution() throws ParserConfigurationException, SAXException, IOException, YFSUserExitException {
// get the input.
Document docUEInput = getDocument("InputUE");
// invoke method to be tested.
Document docActualUEOutput = confirmRefundDistributionUE.confirmRefundDistribution(yfsEnvironment, docUEInput);
// Assert Output
Document docExpectedUEOutput = getDocument("OutputUE");
Assert.assertEquals(XMLUtil.getXMLString(docExpectedUEOutput), XMLUtil.getXMLString(docActualUEOutput));
}
}堆栈跟踪-
javassist.CannotCompileException: by javassist.bytecode.BadBytecode: build ()Lorg/apache/http/impl/client/CloseableHttpClient; in org.apache.http.impl.client.HttpClientBuilder: inconsistent stack height 21
at javassist.CtBehavior.insertBefore(CtBehavior.java:809)
at javassist.CtBehavior.insertBefore(CtBehavior.java:766)
at org.powermock.core.transformers.impl.MainMockTransformer.modifyMethod(MainMockTransformer.java:197)
at org.powermock.core.transformers.impl.MainMockTransformer.allowMockingOfStaticAndFinalAndNativeMethods(MainMockTransformer.java:133)
at org.powermock.core.transformers.impl.MainMockTransformer.transform(MainMockTransformer.java:65)
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:252)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:180)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:70)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:344)
at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
at sun.reflect.annotation.AnnotationParser.parseSig(AnnotationParser.java:439)
at sun.reflect.annotation.AnnotationParser.parseClassValue(AnnotationParser.java:420)
at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724)
at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531)
at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
at java.lang.Class.createAnnotationData(Class.java:3513)
at java.lang.Class.annotationData(Class.java:3502)
at java.lang.Class.getAnnotation(Class.java:3407)
at org.testng.internal.annotations.JDK15AnnotationFinder.findAnnotationInSuperClasses(JDK15AnnotationFinder.java:84)
at org.testng.internal.annotations.JDK15AnnotationFinder.findAnnotation(JDK15AnnotationFinder.java:150)
at org.testng.internal.annotations.AnnotationHelper.findTest(AnnotationHelper.java:31)
at org.testng.internal.MethodHelper.isEnabled(MethodHelper.java:189)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:184)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:653)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: javassist.bytecode.BadBytecode: build ()Lorg/apache/http/impl/client/CloseableHttpClient; in org.apache.http.impl.client.HttpClientBuilder: inconsistent stack height 21
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:119)
at javassist.bytecode.MethodInfo.rebuildStackMap(MethodInfo.java:458)
at javassist.bytecode.MethodInfo.rebuildStackMapIf6(MethodInfo.java:440)
at javassist.CtBehavior.insertBefore(CtBehavior.java:800)
... 37 more
Caused by: javassist.bytecode.BadBytecode: inconsistent stack height 21
at javassist.bytecode.stackmap.Tracer.doOpcode(Tracer.java:81)
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:195)
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:172)
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:116)
... 40 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: 21
at javassist.bytecode.stackmap.Tracer.doASTORE(Tracer.java:422)
at javassist.bytecode.stackmap.Tracer.doOpcode54_95(Tracer.java:299)
at javassist.bytecode.stackmap.Tracer.doOpcode(Tracer.java:75)
... 44 more发布于 2021-09-26 20:57:57
即使您没有使用Maven,您也应该尝试使用一致的依赖项版本。你得到了1.6.2,1.6.4,1.6.6,1.7.4...您应该对所有powermock库使用相同的版本。1.x的最新版本是1.7.4,所以我建议从那里开始。将它们混合在一起是在自找麻烦--对junit4模块的更改可能依赖于核心发行版中的较低级别的更改。
您没有指定您正在使用的java版本,也没有指定httpclient,也没有指定Mockito,所以我必须假设没有兼容性问题。例如,如果您试图在Java 11下使用Powermock 1.x,则可能会遇到问题。
除此之外,我会尝试更新到最新版本的Javassist (在撰写本文时为3.28.0-GA),或者您也可以尝试构建powermock 1.7.4所基于的javassist版本(3.21.0-GA) (但从长远来看,这对您没有帮助)。
如果更新到最新的powermock 1.7.4/javassist仍然得到相同的结果,那么因为您的错误结果是一个非常低级的内部javassist消息(“堆栈高度不一致”),所以任何不熟悉其内部结构的人都不能为您做什么。您的下一步行动可能是尝试更新到Mockito2(这可能还需要更新到PowerMock等)。
你可以尝试在powermock 1.x上发布一个bug,或者在他们的google group中发布一条消息,但是...Powermock 2已经推出好几年了,1.x几乎肯定不再受支持(3年多来一直没有新的1.x版本),所以他们可能也会告诉你先试试PowerMock 2。如果您在升级后仍然得到相同的错误,那么您可能发现powermock/javassist中有一个需要修复的bug,或者应该记录下来的不兼容性。
https://stackoverflow.com/questions/69226468
复制相似问题