2016-09-15 2 views
1

私は、特定のクラスがクラスパス上にあるかどうかをチェックするユーティリティメソッドをテストしようとしています(存在する場合)return true else return falseMock ClassLoader.getSystemClassLoader()。PowermockitoのloadClass

なぜ私はこれをやっているのですか?同じクラスを拡張する独立したクラスにする必要があり、そのうちの1つだけがクラスパス上にあります。特定のものがクラスパスにある場合は、特定のことをする必要があります。

特定のクラスがクラスパス上にあるかどうかを調べるには、以下の種類のメソッドを使用します。 このチェックは、最初のリクエスト後に1回だけ実行されます。 私もClass.forName()をチェックしましたが、以下のアプローチに進むことに決めました。

public static boolean isMyClassOnClassPath() { 
    try { 
     ClassLoader.getSystemClassLoader().loadClass("com.MyClass"); 
     return true; 
    } catch (ClassNotFoundException ex) { 
     return false; 
    } 

}

特定のクラスがクラスパスではないではないようfalse条件を確認するのは簡単です:

私のユーティリティメソッドは次のようになります。 このメソッドがtrueを返すとき、私は肯定的なシナリオのためにJunitを書こうとしています。

@Test 
public void isMyClassOnClassPathShouldReturnTrueWhenMyClassIsOnClassPath() throws Exception{ 
    PowerMockito.mockStatic(MyClass.class); 
    ClassLoader classLoader = PowerMockito.mock(ClassLoader.class); 
    PowerMockito.mockStatic(ClassLoader.class); 
    PowerMockito.when(ClassLoader.getSystemClassLoader()).thenReturn(classLoader); 

    //trying to mock classLoader.loadClass, below way is incorrect 
    //PowerMockito.when(classLoader.loadClass("com.MyClass")).thenReturn(Class<java.lang.Object.class>); 
    Assert.assertTrue(MyClassUtil.isMyClassOnClassPath()); 
} 

classLoader.loadClass()を模擬することは可能ですか?

答えて

3

正直なところ:do not even と思ってください。そのようなことをしていると約と思います。

要するに、あなたは、その人が座っている木の無作為な四肢を切断し始める木の上に座っている人のようです。意味:これはJVMの部分です。あなたのモックがうまくいくと仮定してください:そのメソッドへのすべてのの呼び出し元はあなたのモックローダーを受け取るでしょう!だから、テストケース自体がいくつかのクラスをロードしたいとき、それはあなたのモックに実行されます!

ほとんどいつものように、人々は「私はPowyock for xyzが必要です」と主張するとき、あなたの本当の問題は異なるものです。あなたはテストできないコードを作成しました。その静的呼び出しをそこに置くことで、コードのテストを防ぐことができます。

初心者の方は、hereのように見て、テスト可能なコードを書く方法を学ぶことができます。しかし、場合には、あなたがあなたのデザインを修正することができるか興味がある:

class ClassPathChecker { 
    private final ClassLoader classLoader; 
    ClassPathChecker() { this(ClassLoader.getSystemClassLoader()); } 
    ClassPathChecker(ClassLoader classLoader) { 
    this.classLoader = this.classLoader); 
    } 

    boolean canClassBeLoaded(String className) { 
    try { 
     classLoader.loadClass ... 

上記は嘲笑 ClassLoaderを挿入するために、依存性注入を使用しています。それはあなたにフルが起こっているすべてのものを制御します。 Powermockを使わずに

そして好奇心から:なぜあなたはSystemクラスローダーに制限されますか? Class.forName("yourclass")のような簡単なコールでは同じことを教えてくれませんか?

+0

はい、それを行うのが良い方法です。ありがとう:) Class.forname()に関して私は質問を更新しました。 – YogeshK

関連する問題