2016-03-31 27 views
0

PowerMockの単体テストで使用すると、特定のクラスとその変換に問題があります。PowerMockおよびJavaAssist「クラスの変換に失敗しました」

私はすでに多くのSO応答を見て、PowerMock、JUnit、JavaAssist(依存関係を上書き)の組み合わせを試してみましたが、このクラスで動作する組み合わせは見つかりませんでした。

(PowerMock、JunitとJavaassistの組み合わせにはこの問題はありませんでしたが、無効なスタックフレームが1つ.....そういうこともありましたが、私は別の問題でそれに取り組まなければなりません)。

@PrepareForTest()リストにToplevelPanelクラスを含めると、失敗します。他のJavaFXクラス(Pane.classなど)は問題ありません。

ToplevelPanelが、それについては特に奇妙な何もしています:

public class ToplevelPane extends Region implements BlockContainer, Bundleable { 

Bundleableには@Serializable注釈や特別な何かを持っていません。

ToplevelPanelをテストしていて、@PrepareForTestでwhenNew()を使ってnew()を捕捉したいときや、他のクラスをテストして擬似したいときに失敗します。

誰かが@PrepareForTestにそのようなクラスを可能にするpom.xmlまたはバージョンの組み合わせを共有できる場合は、whenNew()の取得を含めて大いに感謝します。

このポストの最後に、失敗のスタックトレースがあります。

の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> 

ユニットテストコード

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"); 
    } 
} 

失敗STACKTRACE

java.lang.IllegalStateException:名前を持つクラスを変換に失敗しました nl.utwente.viskell .ui.ToplevelPane。理由: javassist.bytecode.InterfaceMethodrefInfoは org.powermock.core.classloader.MockClassLoaderで org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:219) で javassist.bytecode.MethodrefInfoにキャストすることはできません ジャワでjava.lang.ClassLoader.loadClass(ClassLoader.java:357)で org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:67) で.loadModifiedClass(MockClassLoader.java:147) 。 lang.Class.forName0(ネイティブメソッド)at java.lang.Class.forName(Class.java:348)at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114) でsun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125) でsun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) sun.reflect.annotationで.AnnotationParser.parseSig(AnnotationParser.java:439) でsun.reflect.annotation.AnnotationParser.parseClassValue(AnnotationParser.java:420) でsun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser。Javaの: で724) でsun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531) sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355) sun.reflect.annotationで.AnnotationParser.parseAnnotation2 sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)で(AnnotationParser.java:286) でsun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72) (Class.java:3521)at java.lang.Class.annotationData(Class.java:3510)の でjava.lang.Class.getAnnotation org.junit.internal.runners.TestClass.getAnnotatedMethods(TestClass.java:45) でのN org.junit.internal.MethodSorter.getDeclaredMethodsで(Class.java:3415)(MethodSorter.java:52) org.junit.internal.runnersで org.junit.internal.runners.MethodValidator.validateStaticMethods(MethodValidator.java:44) でorg.junit.internal.runners.MethodValidator.validateTestMethods(MethodValidator.java:71) 。のMethodValidator.validateMethodsForDefaultRunner org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.validate(PowerMockJUnit44RunnerDelegateImpl.java:108)で(MethodValidator.java:50) org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl。(PowerMockJUnit44RunnerDelegateImpl.java:70) org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImplで。(PowerMockJUnit47RunnerDelegateImpl.java:42) におけるORG .powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl。(PowerMockJUnit49RunnerDelegateImpl.java:25) sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)でsun.reflect.NativeConstructorAccessorImpl.newInstance0(ネイティブ 方法)に at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at jav org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:143) org.powermockで でa.lang.reflect.Constructor.newInstance(Constructor.java:422) 。 modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:39) org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:217) org.powermockで で 。 modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl。(JUnit4TestSuiteChunkerImpl.java:59) at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRun NER。(AbstractCommonPowerMockRunner.java:32) org.powermock.modules.junit4.PowerMockRunnerで。(PowerMockRunner.java:33) sun.reflect.NativeConstructorAccessorImplでsun.reflect.NativeConstructorAccessorImpl.newInstance0(ネイティブ 方法)に org.junitで.newInstance sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)で(NativeConstructorAccessorImpl.java:62) java.lang.reflect.Constructor.newInstance(Constructor.java:422)で .internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:29) at org.junit.internal.builders.AnnotatedBuilder。 org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)でrunnerForClass(AnnotatedBuilder.java:21) でorg.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59) com.intellij.junit4でorg.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)で org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59) で com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)で.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:41) でcom.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.javaでsun.reflect.NativeMethodAccessorImpl.invoke0(ネイティブメソッド)で 。 java.lang.ClassCastExceptionが:によって引き起こさ62) でcom.intellij.rt.execution.application.AppMain.main(AppMain.java:140) javassist.bytecode.InterfaceMethodrefInfoは javassist.bytecodeにキャストすることはできません。 javassist.bytecode.stackmap.Tracer.doOpcode148_201でjavassist.bytecode.stackmap.Tracer.doInvokeMethod(Tracer.java:800)で javassist.bytecode.ConstPool.getMethodrefType(ConstPool.java:452)でMethodrefInfo(Tracer.java :597) at javassist.bytecode.stackmap.Tracer.doOpcode(Tracer.java:81) javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:187)at javassist.bytecode.stackmap.MapMaker.make(MapMaker。 (MapMaker.java:164)を に設定してください。 javassist.CtBehavior.insertBefore(CtBehavior.java:734)でjavassist.CtBehavior.insertBeforeで javassist.bytecode.MethodInfo.rebuildStackMapIf6(MethodInfo.java:405) (CtBehavior.java:768)でMethodInfo.java:423) at org.powermock.core.transformers.impl.MainMockTransformer.modifyMethod(MainMockTransformer.java:2) 06) org.powermock.core.transformers.impl.MainMockTransformer.allowMockingOfStaticAndFinalAndNativeMethods(MainMockTransformer.java:142) org.powermock.core.transformers.impl.MainMockTransformer.transform(MainMockTransformer.java:65で ) ATで より org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:215) ... 56あなたが本当にテストのために準備する必要がある場合は残念ながら、この問題は場合には、今は解決できない

答えて

0

ToplevelPaneクラス。しかし、私はそれが必要であるかどうかはわかりません。 ToplevelPaneクラスに静的メソッドまたは最終メソッドがないことに気付きました。注釈からToplevelPaneを削除すると、テストは別のエラーで失敗します。

sun.reflect.DelegatingConstructorAccessorImplで でsun.reflect.NativeConstructorAccessorImpl.newInstance0(ネイティブメソッド) でjava.lang.ExceptionInInitializerError sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 。 newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at java.lang.Class.newInstance(Class。Javaの:442) sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)へ javafx.fxml.FXMLLoader $ InstanceDeclarationElement.constructValue(FXMLLoader.java:1009) にjavafx.fxml.FXMLLoader $価値要素に.processStartElement(FXMLLoader.java:746)javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)に に にjavafx.fxml.FXMLLoader.loadImpl nl.utwenteにnl.utwente.viskell.ui.ComponentLoader.loadFXML(ComponentLoader.java:25)に javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)に(FXMLLoader.java:2441)。 viskell.ui.components.ValueBlock。(ValueBlock.java:48) nl.utwente.viskell.ui.components.ConstantBlock に(ConstantBlock.java:25)太陽に sun.reflect.NativeMethodAccessorImpl.invoke0(代替法)ValueBlockTest.outputTest(ValueBlockTest.java:33)に にjava.lang.reflect.Method.invoke(Method.java:498)に sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) に.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:316) にorg.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)へorg.junit.internal.runners.MethodRoadie $ 2.run(MethodRoadie.java:89) にorg.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97) にorg.powermock.modules。 junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:300) にorg.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131) する組織。 powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.access $ 100(PowerMockJUnit47RunnerDelegateImpl.java:59) へorg.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner $ TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147) にorg.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl。 Javaの:107) にorg.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82) にorg.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner。 org.junit.iにrunBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:288) nternal.runners.MethodRoadie.runTest(MethodRoadie.java:87)org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)へ へ org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl .invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:208) にorg.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:147)にorg.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ 1.run(PowerMockJUnit44RunnerDelegateImpl.java:121) org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) にorg.junit.internalへ。runners.ClassRoadie.runProtected org.powermock.modules.junit4.commonで org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:123) で(ClassRoadie.java:44) 。 internal.impl.JUnit4TestSuiteChunkerImpl.run org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)で(JUnit4TestSuiteChunkerImpl.java:123) org.powermock.modulesで 。 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)でorg.junit.runner.JUnitCore.run(JUnitCore.java:137)でjunit4.PowerMockRunner.run(PowerMockRunner.java:59) でcom.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234) でcom.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74) 日で。 reflect.NativeMethodAccessorImpl.invoke0 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)java.lang.reflectので でsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)での(ネイティブメソッド) 。 Method.invoke(Method.java:498)at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 原因:java.lang.IllegalStateException:ツールキットが初期化されていない at com.sun.javafx.applicationで com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:268) でcom.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:273) 。 com.sun.javafx.application.PlatformImpl.setDefaultPlatformUserAgentStylesheet(PlatformImpl.java:512)javafx.scene.control.Controlで でPlatformImpl.setPlatformUserAgentStylesheet(PlatformImpl.java:550) 。(Control.java:87)..最新バージョンへのアップデートJavassistのであれば。51 より

、その後、CGLIBは、Javassistのコードを修正するために奇妙なプロキシクラスを作成し、そのJVMはをスローします。 Mockito 1とPowerMockは、もはやサポートされていないcglib 2を使用します。

Mockitoはバージョン2以降ByteButtyに移行されましたが、ベータ版のみです。 PowerMockもByteButtyに移行する予定だが、6月末よりも早くなるとは思っていない。

次のPowerMockリリース(1.6.5)でこの問題に取り組もうとしていますが、実現可能かどうかはわかりません。

私はバグトラッカーでissueを作成しました。ところで、私はjavafx.scene.layout.Regionが嘲笑された場合に問題を再現できます。

+0

応答アーサーのおかげで大変感謝しています。私は確かに他のバージョンを使用してVerifyErrorsに遭遇しました。 テストを実行するときにJVMに渡すことを避けることができますが、私はこのプロジェクトにそのルートを行きたくありませんでした...とにかく私はプロジェクトに従うことができますか、この特定のものへのアップデートを取得しますか? –

+0

バグトラッカーで[問題](https://github.com/jayway/powermock/issues/654)を作成しました。ところで、「ToplevelPane」のテスト準備の理由がないことを知りました。ソースでは、 'ToplevelPane'クラスに静的メソッドまたは最終メソッドはありません。アノテーションから 'ToplevelPane'を削除すると、テストは別のエラーで失敗します。また、 'javafx.scene.layout.Region'が嘲笑された場合にも問題を再現できます。 –

+0

問題をお寄せいただき、ありがとうございます。私はwhenNew()(私は他の場所でそれを読んだことがあります)でそれから他の模擬クラスへのnew()呼び出しを "キャッチ"したい場合、テストのためにToplevelPaneを準備する必要があると思います。いくつかのFXクラスはOKで、他のFXクラスは失敗します - 理由はありません... –

関連する問題