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あなたが本当にテストのために準備する必要がある場合は残念ながら、この問題は場合には、今は解決できない
応答アーサーのおかげで大変感謝しています。私は確かに他のバージョンを使用してVerifyErrorsに遭遇しました。 テストを実行するときにJVMに渡すことを避けることができますが、私はこのプロジェクトにそのルートを行きたくありませんでした...とにかく私はプロジェクトに従うことができますか、この特定のものへのアップデートを取得しますか? –
バグトラッカーで[問題](https://github.com/jayway/powermock/issues/654)を作成しました。ところで、「ToplevelPane」のテスト準備の理由がないことを知りました。ソースでは、 'ToplevelPane'クラスに静的メソッドまたは最終メソッドはありません。アノテーションから 'ToplevelPane'を削除すると、テストは別のエラーで失敗します。また、 'javafx.scene.layout.Region'が嘲笑された場合にも問題を再現できます。 –
問題をお寄せいただき、ありがとうございます。私はwhenNew()(私は他の場所でそれを読んだことがあります)でそれから他の模擬クラスへのnew()呼び出しを "キャッチ"したい場合、テストのためにToplevelPaneを準備する必要があると思います。いくつかのFXクラスはOKで、他のFXクラスは失敗します - 理由はありません... –