2017-07-28 13 views
1

残念ながら静的メソッド呼び出しを持つ別のクラスを拡張する(JukitoとMockitoを使用して)クラスをテストしようとしています。何とかこの呼び出しをスキップすることは可能ですか?私はPowerMockitoを使いたくないです。Jukito/Mockito静的メソッドでのテスト

public class A extends B { 

    @Inject 
    public A(final String s){ 
     super(s); 
    } 
} 

public abstract class B { 

    private String s; 

    protected String m = C.get().createUniqueId(); //Exception is thrown here 

    public B(String s){ 
     this.s = s; 
    } 
} 

public class C { 
    private static C c; //assume this is never null 

    public static C get() { 
     return c; 
    } 

    public final native String createUniqueId() {} 

} 

@RunWith(JukitoRunner.class) 
public class ATest { 

    @Inject 
    A a; 

    @Test 
    public void onMethod1Test(){ 
    } 
} 

ATESTを実行しているとき、私は次のエラーを取得する:

Error injecting constructor, java.lang.UnsatisfiedLinkError: C

私はそれがあるため、静的メソッドのだと仮定は、私間違っていましたか?

すべてのクラスは私の実際のクラスの単なる例であり、Cクラスはmyによって書かれたものではなく、(残念ながら)変更できないことに注意してください。しかし、私のクラスの背後にあるアイデアは同じです。名前を変更して関連する部分だけを残しました。

答えて

1

Jukito claims

The combined power of JUnit, Guice and Mockito.

しかし、事は次のとおりです。これらの製品はいずれもモック静的メソッドにあなたを可能にしません。

PowerMock(ito)とJMockitが可能な唯一のフレームワークです。

すでに説明したように、普通はtestableコード(静的呼び出しを避ける)を書くだけで、この「不足」を「回避」します。しかし、設計を改善することができないので、これらの2つの選択肢のみ:このクラスのテストにはPowerMock(ito)を使用するか、テストしません。

+0

私はこれをすべて知っていましたが、私は何かを見逃していたと思っています。私はPowerMockitoの使用に熱心ではなく、Cクラスを書き直すことができないので、今はクラスをテストしません。私はあなたの答えを受け入れるでしょう、あなたは時間をかけて簡単な説明を書いています。 – CrazySabbath

0

したがって、を使用して、Bの新しいインスタンスにmを生成することです。あなたはCを制御せず、あなたはそれをテストする方法を理解しようとしていますよね?私はあなたがあなたの毒を選ぶ必要があると思うが、私はあなたの状況のた​​めの "毒"の別の選択について考えることができる。

あなたはその後、そうでない場合は適切であろうBの静的フィールドを追加し、より多くのアクセスを与える:今、あなたのテストで嘲笑インスタンスにB.cを再割り当てすることができ

public abstract class B { 
    static C c = C.get(); 
    private String s; 
    protected String m = c.createUniqueId(); 
    public B(String s){ 
    this.s = s; 
    } 
} 

。私はJUnitとSpockについてもっとよく知っていますので、私はあなたにその仕組みを理解させてもらうつもりです。単体テストはテストするクラスと同じパッケージに入っているので、パッケージのプライベートスコープを使用できます。 ABとは別のパッケージにある場合は、protectedにプロモートする必要があります。これはすばやく簡単ですが、他のコードをB.cに再割り当てする可能性があります。 Aを全くテストしないリスクに対しては、リスクを判断する必要があります。

また、Cを非表示にするためにクラスとインターフェイスを追加することを検討して、ABを完全に削除することも考えられます。基本的には、mを生成するためにSupplier<String>を持つBFactoryのようなものを作成します。単体テストではサプライヤを模擬し、実稼働環境ではCに基づく実装を使用します。私が考えることができるすべての方法は面倒です、またはBのすべてのサブクラスが同じようにmを生成するよう強制しません。唯一の例外は、実際には合成を使用して、のインスタンスをAに配置する方が実際に意味がある場合です。それから、あなたはそれを行うためのまともな方法を持っているかもしれません。

関連する問題