2016-09-01 5 views
3

私はそれをググはClass.forNameのとclass.Constructor.newInstanceを模擬するためにどのように()

clazz = Class.forName("Complete Class path") 
Object obj = clazz.Constructor().getInstance(); 

を欺くしようとしている、とpowermockを使用して静的メソッドを模擬する方法を知らされたリンクを発見されています。私は

Class.forName("Complete Class path")

Object obj = clazz.Constructor().getInstance()を模擬するために、これらのロジックを使用してみましたが、エラーに直面してきました。

at sun.reflect.GeneratedSerializationConstructorAccessor16.newInstance(Unknown Source) [junit] 
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) [junit] 
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:45) [junit] 
at org.powermock.reflect.internal.WhiteboxImpl.newInstance(WhiteboxImpl.java:223) [junit] 
at org.powermock.reflect.Whitebox.newInstance(Whitebox.java:139) [junit] 
at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:64) [junit] 
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:203) [junit] 
at org.powermock.api.extension.listener.AnnotationEnabler.standardInject(AnnotationEnabler.java:106) [junit] 
at org.powermock.api.extension.listener.AnnotationEnabler.beforeTestMethod(AnnotationEnabler.java:54) [junit] 
at org.powermock.tests.utils.impl.PowerMockTestNotifierImpl.notifyBeforeTestMethod(PowerMockTestNotifierImpl.java:90) [junit] 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:292) [junit] 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127) [junit] 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82) [junit] 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282) [junit] 
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87) [junit] 
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50) [junit] 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207) [junit] 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146) [junit] 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120) [junit] 
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) [junit] 
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) [junit] 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122) [junit] 
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106) [junit] 
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) 
+6

私は聞いてみよう:なぜあなたはそれをしたいですか? – GhostCat

+0

その他:「面接」のエラーは良い出発点ではありません。詳細を教えてください。そうしないと、役に立つフィードバックが表示されません。 – GhostCat

+0

しないでください。コードを再構成して、それを嘲笑する必要はありません。工場を通過する。 –

答えて

1

私はあなたが原因の早期Classロードの事実に静的forNameメソッドをあざけると成功しないだろうと思います。私はそれを行うことができるモックフレームワークを知らない。

しかし、あなたはあなた自身のコードをテストしているならば、私はあなたがClass.forNameを必要な場所にそれを使用するようにコードを書き換えて、あなたのテストでモックで置き換え

このstrategy

interface ClassLoadingStrategy { 
    ClassLoadingStrategy DEFAULT = Class::forName; 

    Class<?> forName(final String name) throws Exception; 
} 
Class.forNameロジックを移動するために、あなたをお勧めしたいです。

+0

そんなことは簡単にできません。 java.lang.Classはfinalです。だから彼はクラスのインスタンスを模擬するためにPowerMockが必要だと思う。 – GhostCat

+0

@GhostCatそれを再チェックする必要がありますが、ブートストラップクラスローダーによってロードされた最終クラスをモックすることは不可能です(つまり、javaエージェントを使用する)ことができません。 – vsminkov

1

私はClassを嘲笑するのは良い考えではないと思うので、コードを書き換えてテストしやすくする必要があります。あなたは、コンポーネントの作成をファクトリに委譲する必要があります。そして、それを模擬するのは簡単でしょう。あなたができる、

public interface MyObjectFactory { 
    MyObject create(); 
} 

次にあなたがこのオブジェクトを作成する必要があるクラスでは、あなたが一度に行わ場

public class MyClass { 
    // The factory that will create my objects 
    private MyObjectFactory factory; 

    public void someMethod() { 
     // Calls the factory to create my object 
     MyObject object = factory.create(); 
     ... 
    } 
} 

として工場を追加します。ここでは

は、あなたの工場のように見えることができるかでありますあなたの選択したMyObjectのインスタンスを提供するためにMyObjectFactoryを模倣するためにMockitoを使用してください。

テストケースは次のようになります。

@RunWith(MockitoJUnitRunner.class) 
public class MyClassTest { 

    @Mock 
    MyObjectFactory factory; 
    @InjectMocks 
    MyClass myClass = new MyClass(); 

    @Test 
    public void testSomeMethod() { 
     ... 
     Mockito.when(factory.create()).thenReturn(myObject); 
     // Call the method 
     myClass.someMethod(); 
    } 
} 
+0

私は同意します。誰かがあなたの道に不動の物を置くならば。あなたはそのことを動かす時間を無駄にしません。あなたは歩き回る。そしてあなたのアプローチは、まさに「歩く」最良の方法です! – GhostCat

+0

工場をテストしている場合はどうなりますか? : -/ – Yuval

+0

@Yuvalそれは別の質問/件名になります –

関連する問題