2016-03-31 10 views
0

Ich habe ein Problem mit bestimmten Klassen und deren Umwandlung, wenn sie in Komponententests mit PowerMock verwendet werden.PowerMock & JavaAssist "Fehler beim Umwandeln der Klasse"

Ich habe bereits viele SO-Antworten betrachtet und viele Kombinationen von PowerMock, JUnit, JavaAssist (übergeordnete Abhängigkeiten) ausprobiert, kann aber keine Kombination finden, die für diese Klasse funktioniert.

(Einige Kombinationen von PowerMock, Junit und Javaassist hatten dieses Problem nicht, aber der ungültige Stackframe ... also stecken auch da - aber das müsste ich in einer separaten SO-Frage angehen).

Wenn ich die Klasse ToplevelPanel in der @ PrepareForTest() - Liste einschließen, schlägt es fehl. Andere JavaFX-Klassen (wie Pane.class) verursachen kein Problem.

ToplevelPanel hat nichts besonders merkwürdig darüber:

public class ToplevelPane extends Region implements BlockContainer, Bundleable { 

Bundleable hat keine @Serializable Anmerkungen oder etwas Besonderes.

Dies schlägt fehl, wenn ich ToplevelPanel testen und möchte es in @PrepareForTest in der Lage sein, neue() 's über whenNew() abzufangen, und wenn ich andere Klassen testen und es verspotten möchte.

Wenn jemand eine pom.xml oder eine Versionskombination teilen kann, die mir @PrepareForTest eine solche Klasse ermöglicht, einschließlich der Erfassung von whenNew() würde es sehr geschätzt werden.

Am Ende dieses Beitrags finden Sie den Stack-Trace des Fehlers.

pom.xml

<properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    <junit.version>4.11</junit.version> 
    <powermock.version>1.5.1</powermock.version> 
    </properties> 

<dependency> 
    <groupId>junit</groupId> 
    <artifactId>junit</artifactId> 
    <version>${junit.version}</version> 
    <scope>test</scope> 
</dependency> 
<dependency> 
    <groupId>org.powermock</groupId> 
    <artifactId>powermock-module-junit4</artifactId> 
    <version>${powermock.version}</version> 
    <scope>test</scope> 
</dependency> 
<dependency> 
    <groupId>org.powermock</groupId> 
    <artifactId>powermock-api-mockito</artifactId> 
    <version>${powermock.version}</version> 
    <scope>test</scope> 
</dependency> 

Einheit Test-Code

import nl.utwente.viskell.haskell.env.Environment; 
import nl.utwente.viskell.haskell.type.Type; 
import nl.utwente.viskell.ui.ToplevelPane; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

import static org.junit.Assert.assertEquals; 
import static org.mockito.Matchers.any; 
import static org.mockito.Mockito.RETURNS_DEEP_STUBS; 
import static org.powermock.api.mockito.PowerMockito.mock; 
import static org.powermock.api.mockito.PowerMockito.when; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Type.class, ToplevelPane.class, Environment.class}) 
public class ValueBlockTest { 
    private ToplevelPane mockToplevelPane; 

    @Before 
    public void Setup() { 
     mockToplevelPane = mock(ToplevelPane.class, RETURNS_DEEP_STUBS); 
     Environment mockEnv = mock(Environment.class); 
     Type mockType = mock(Type.class); 
     when(mockEnv.buildType(any())).thenReturn(mockType); 
     when(mockToplevelPane.getEnvInstance()).thenReturn(mockEnv); 
    } 

    @Test 
    public void outputTest() throws Exception { 
     ConstantBlock block = new ConstantBlock(mockToplevelPane, Type.con("Float"), "0.0", true); 
     block.setValue("6"); 
     assertEquals(block.getValue(), "6"); 
    } 
} 

Failure Stacktrace

java.lang.IllegalStateException: Fehler Klasse verwandeln mit Namen nl.utwente.viskell .UI.TopelPane. Grund: javassist.bytecode.InterfaceMethodrefInfo kann nicht auf javassist.bytecode.MethodrefInfo bei org.powermock.core.classloader.MockClassLoader.loadMockClass (MockClassLoader.java:219) bei org.powermock.core.classloader.MockClassLoader gegossen werden .loadModifiedClass (MockClassLoader.java:147) bei org.powermock.core.classloader.DeferSupportingClassLoader.loadClass (DeferSupportingClassLoader.java:67) bei java.lang.ClassLoader.loadClass (ClassLoader.java:357) bei Java. lang.Class.forName0 (Native Method) unter java.lang.Class.forName (Class.java:348) unter sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType (CoreReflectionFactory.java:114) bei sun.reflect.generics.visitor.Reifier.visitClassTypeSignature (Reifier.java:125) bei sun.reflect.generics.tree.ClassTypeSignature.accept (ClassTypeSignature.java:49) bei sun.reflect.annotation .AnnotationParser.parseSig (AnnotationParser.java:439) bei sun.reflect.annotation.AnnotationParser.parseClassValue (AnnotationParser.java:420) bei sun.reflect.annotation.AnnotationParser.parseClassArray (AnnotationParser.Java: 724) bei sun.reflect.annotation.AnnotationParser.parseArray (AnnotationParser.java:531) bei sun.reflect.annotation.AnnotationParser.parseMemberValue (AnnotationParser.java:355) bei sun.reflect.annotation .AnnotationParser.parseAnnotation2 (AnnotationParser.java:286) bei sun.reflect.annotation.AnnotationParser.parseAnnotations2 (AnnotationParser.java:120) bei sun.reflect.annotation.AnnotationParser.parseAnnotations (AnnotationParser.java:72) bei java.lang.Class.createAnnotationData (Class.java:3521) um java.lang.Class.annotationData (Class.java:3510) um java.lang.Class.getAnnotatio n (Class.java:3415) bei org.junit.internal.MethodSorter.getDeclaredMethods (MethodSorter.java:52) bei org.junit.internal.runners.TestClass.getAnnotatedMethods (TestClass.java:45) bei org.junit.internal.runners.MethodValidator.validateTestMethods (MethodValidator.java:71) bei org.junit.internal.runners.MethodValidator.validateStaticMethods (MethodValidator.java:44) bei org.junit.internal.runners. MethodValidator.validateMethodsForDefaultRunner (MethodValidator.java:50) bei org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.validate (PowerMockJUnit44RunnerDelegateImpl.java:108) bei org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl. (PowerMockJUnit44RunnerDelegateImpl.java:70) bei org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl. (PowerMockJUnit47RunnerDelegateImpl.java:42) bei org .powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl. (PowerMockJUnit49RunnerDelegateImpl.java:25) bei sun.reflect.NativeConstructorAccessorImpl.newInstance0 (Mutter Method) bei sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:62) um sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:45) bei jav a.lang.reflect.Constructor.newInstance (Constructor.java:422) bei org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader (JUnit4TestSuiteChunkerImpl.java:143) bei org.powermock. modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader (JUnit4TestSuiteChunkerImpl.java:39) bei org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators (AbstractTestSuiteChunkerImpl.java:217) bei org.powermock. modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl. (JUnit4TestSuiteChunkerImpl.java:59) um org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRun ner. (AbstractCommonPowerMockRunner.java:32) bei org.powermock.modules.junit4.PowerMockRunner. (PowerMockRunner.java:33) bei sun.reflect.NativeConstructorAccessorImpl.newInstance0 (Mutter Method) bei sun.reflect.NativeConstructorAccessorImpl .newInstance (NativeConstructorAccessorImpl.java:62) bei sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:45) bei java.lang.reflect.Constructor.newInstance (Constructor.java:422) bei org.junit .internal.builders.AnnotatedBuilder.buildRunner (AnnotatedBuilder.java:29) unter org.junit.internal.builders.AnnotatedBuilder.runnerForClass (AnnotatedBuilder.java:21) bei org.junit.runners.model.RunnerBuilder.safeRunnerForClass (RunnerBuilder.java:59) bei org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass (AllDefaultPossibilitiesBuilder.java:26) bei org.junit.runners.model.RunnerBuilder.safeRunnerForClass (RunnerBuilder.java:59) bei org.junit.internal.requests.ClassRequest.getRunner (ClassRequest.java:26) bei com.intellij.junit4 .JUnit4IdeaTestRunner.startRunnerWithArgs (JUnit4IdeaTestRunner.java:41) unter com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart (JUnitStarter.java:212) bei com.intellij.rt.execution.junit.JUnitStarter.main (JUnitStarter.java:68) bei sun.reflect.NativeMethodAccessorImpl.invoke0 (native Methode) bei sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java: 62) bei com.intellij.rt.execution.application.AppMain.main (AppMain.java:140) verursacht durch: java.lang.ClassCastException: javassist.bytecode.InterfaceMethodrefInfo kann nicht auf javassist.bytecode gegossen werden. MethodrefInfo bei javassist.bytecode.ConstPool.getMethodrefType (ConstPool.java:452) bei javassist.bytecode.stackmap.Tracer.doInvokeMethod (Tracer.java:800) bei javassist.bytecode.stackmap.Tracer.doOpcode148_201 (Tracer.java : 597) bei javassist.bytecode.stackmap.Tracer.doOpcode (Tracer.java:81) um javassist.bytecode.stackmap.MapMaker.make (MapMaker.java:187) um javassist.bytecode.stackmap.MapMaker.make (MapMaker. java: 199) um javassist.bytecode.stackmap.MapMaker.make (MapMaker.java:164) um javassist.bytecode.stackmap.MapMaker.make (MapMaker.java:108) um ​​ javassist.bytecode.MethodInfo.rebuildStackMap (MethodInfo.java:423) bei javassist.bytecode.MethodInfo.rebuildStackMapIf6 (MethodInfo.java:405) bei javassist.CtBehavior.insertBefore (CtBehavior.java:768) bei javassist.CtBehavior.insertBefore (CtBehavior.java:734) unter org.powermock.core.transformers.impl.MainMockTransformer.modifyMethod (MainMockTransformer.java:2 06) bei org.powermock.core.transformers.impl.MainMockTransformer.allowMockingOfStaticAndFinalAndNativeMethods (MainMockTransformer.java:142) bei org.powermock.core.transformers.impl.MainMockTransformer.transform (MainMockTransformer.java:65) bei org.powermock.core.classloader.MockClassLoader.loadMockClass (MockClassLoader.java:215) ... 56 mehr

Antwort

0

Leider kann diese Frage jetzt nicht in Fall gelöst werden, wenn Sie wirklich brauchen für Test vorzubereiten dem ToplevelPane Klasse. Aber ich bin mir nicht sicher, ob es nötig ist. Ich habe festgestellt, dass die Klasse ToplevelPane keine statische oder endgültige Methode hat. Und wenn Sie ToplevelPane aus Annotation entfernen, schlägt der Test mit einem anderen Fehler fehl.

java.lang.ExceptionInInitializerError bei sun.reflect.NativeConstructorAccessorImpl.newInstance0 (native Methode) bei sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:62) bei sun.reflect.DelegatingConstructorAccessorImpl. newInstance (DelegatingConstructorAccessorImpl.java:45) bei java.lang.reflect.Constructor.newInstance (Constructor.java:423) bei java.lang.Class.newInstance (Klasse.java: 442) zu sun.reflect.misc.ReflectUtil.newInstance (ReflectUtil.java:51) zu javafx.fxml.FXMLLoader $ InstanceDeclarationElement.constructValue (FXMLLoader.java:1009) zu javafx.fxml.FXMLLoader $ Wert Element .processStartElement (FXMLLoader.java:746) zu javafx.fxml.FXMLLoader.processStartElement (FXMLLoader.java:2707) zu javafx.fxml.FXMLLoader.loadImpl (FXMLLoader.java:2527) zu javafx.fxml.FXMLLoader.loadImpl (FXMLLoader.java:2441) zu javafx.fxml.FXMLLoader.load (FXMLLoader.java:2409) zu nl.utwente.viskell.ui.ComponentLoader.loadFXML (ComponentLoader.java:25) zu nl.utwente. viskell.ui.components.ValueBlock. (ValueBlock.java:48) bis nl.utwente.viskell.ui.components.ConstantBlock. (ConstantBlock.java:25) zu ValueBlockTest.outputTest (ValueBlockTest.java:33) zu sun.reflect.NativeMethodAccessorImpl.invoke0 (Alternative Methode) Sun .reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) zu sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) zu java.lang.reflect.Method.invoke (Method.java:498) zu org.junit.internal.runners.TestMethod.invoke (TestMethod.java:68) zu org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runTestMethod (PowerMockJUnit44RunnerDelegateImpl.java:316) zu 01.235.org.junit.internal.runners.MethodRoadie $ 2.run (MethodRoadie.java:89) zu org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters (MethodRoadie.java:97) zu org.powermock.modules. junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.executeTest (PowerMockJUnit44RunnerDelegateImpl.java:300) zu org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTestInSuper (PowerMockJUnit47RunnerDelegateImpl.java:131) zu org. powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.access $ 100 (PowerMockJUnit47RunnerDelegateImpl.java:59) zu org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner $ TestExecutorStatement.evaluate (PowerMockJUnit47RunnerDelegateImpl.java:147) zu org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.evaluateStatement (PowerMockJUnit47RunnerDelegateImpl. java: 107) zu org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTest (PowerMockJUnit47RunnerDelegateImpl.java:82) zu org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner. runBeforesThenTestThenAfters (PowerMockJUnit44RunnerDelegateImpl.java:288) zu org.junit.i nternal.runners.MethodRoadie.runTest (MethodRoadie.java:87) zu org.junit.internal.runners.MethodRoadie.run (MethodRoadie.java:50) zu org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl .invokeTestMethod (PowerMockJUnit44RunnerDelegateImpl.java:208) zu org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods (PowerMockJUnit44RunnerDelegateImpl.java:147) zu org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ 1.run (PowerMockJUnit44RunnerDelegateImpl.java:121) zu org.junit.internal.runners.ClassRoadie.runUnprotected (ClassRoadie.java:34) zu org.junit.internal.runners.ClassRoadie.runProtected (ClassRoadie.java:44) bei org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run (PowerMockJUnit44RunnerDelegateImpl.java:123) bei org.powermock.modules.junit4.common. internal.impl.JUnit4TestSuiteChunkerImpl.run (JUnit4TestSuiteChunkerImpl.java:123) bei org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run (AbstractCommonPowerMockRunner.java:53) bei org.powermock.modules. junit4.PowerMockRunner.run (PowerMockRunner.java:59) bei org.junit.runner.JUnitCore.run (JUnitCore.java:137) bei com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs (JUnit4IdeaTestRunner.java:69) bei com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart (JUnitStarter.java:234) bei com.intellij.rt.execution.junit.JUnitStarter.main (JUnitStarter.java:74) bei Sonne. reflect.NativeMethodAccessorImpl.invoke0 (native Methode) bei sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) bei sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) bei java.lang.reflect. Method.invoke (Method.java:498) um ​​ com.intellij.rt.execution.application.AppMain.main (AppMain.java:144) verursacht durch: java.lang.IllegalStateException: Toolkit nicht initialisiert um com.sun.javafx.application.PlatformImpl.runLater (PlatformImpl.java:273) bei com.sun.javafx.application.PlatformImpl.runLater (PlatformImpl.java:268) bei com.sun.javafx.application. PlatformImpl.setPlatformUserAgentStylesheet (PlatformImpl.java:550) bei com.sun.javafx.application.PlatformImpl.setDefaultPlatformUserAgentStylesheet (PlatformImpl.java:512) bei javafx.scene.control.Control. (Control.java:87) .. . 51 mehr

Wenn Update Javassist auf die neueste Version, danncGLIB schafft seltsame Proxy-Klasse für mit Javassist Code geändert, so JVM wirft. Mockito 1 und PowerMock verwenden cglib 2, das nicht mehr unterstützt wird.

Mockito wurde seit Version 2 zu ByteButty migriert, aber nur Beta. PowerMock wird auch zu ByteButty wechseln, aber ich bezweifle, dass es früh als Ende Juni sein wird.

Ich werde versuchen, dieses Problem in der nächsten PowerMock-Version (1.6.5) anzugehen, aber ich bin nicht sicher, ob es machbar ist.

Ich habe eine issue in unserem Bug-Tracker erstellt. Übrigens kann ich das Problem reproduzieren, wenn die javafx.scene.layout.Region verspottet wird.

+0

Vielen Dank für die Antwort Arthur. Ich habe tatsächlich in die VerifyErrors geraten, wenn ich andere Versionen verwende. Das kann sein, die Weitergabe zu vermeiden --noverify an die JVM bei der Durchführung von Tests, aber ich wollte diese Route auf diesem Projekt nicht gehen ... Wie auch immer, ich kann ein Projekt verfolgen oder ein Update erhalten zu diesem bestimmten? –

+0

Ich habe ein [Problem] (https://github.com/jayway/poweramock/issues/654) in unserem Bug-Tracker erstellt. Übrigens, ich habe herausgefunden, dass es keinen Grund gibt, sich auf den 'ToplevelPane' vorzubereiten. Wie ich in Quelle sehe, hat die 'ToplevelPane' Klasse keine statische oder finale Methode. Und wenn 'ToplevelPane' aus Annotation entfernt wird, schlägt der Test mit einem anderen Fehler fehl. Ich kann das Problem auch reproduzieren, falls die 'javafx.scene.layout.Region' gespottet wird. –

+0

Danke für das Problem, wird es verfolgen.Ich glaube, ich muss ToplevelPane für den Test vorbereiten, wenn ich neue() Aufrufe an andere verspottete Klassen von ihm mit whenNew() "fangen" will (ich habe das an anderer Stelle gelesen). Einige FX-Klassen sind in Ordnung, andere scheitern - keine Ahnung warum ... –