2016-03-23 12 views
0

私は次の行をモックとしたい:finalクラスを返す静的メソッドをモックする方法は?

Bigquery bigquery = Transport.newBigQueryClient(options).build(); 

ここでの問題は、newBigQueryClient方法は最終的なものでBulderクラスを返すことです。これは、mockitoまたはpowermockito(これはそのような例外を返します:最終クラスをサブクラス化できません)とどちらでも嘲ることができないことを意味しますが、その上にメソッドを作成するのに適した何かを返す必要があります。どのようにそれを行うにはどのようなアイデア?

+0

BigQueryは拡張できますか(クラスの場合)か実装されていますか(インターフェースの場合)? – Seelenvirtuose

+0

なぜインスタンスを作成して代わりに返さないのですか? – aribeiro

+0

そのクラスとそれを拡張することが可能です。 @Seelenvirtuose – Yevgen

答えて

2

提案はあなたのコードを改善するために、それははるかにテスト可能作る:すべての

まず、あなたは一例として私たちを与えた割り当てのような声明を嘲笑していません。 オブジェクトを模倣し、型がスーパータイプを表す変数に参照を割り当てます。

さらに、あなたが何かを離れて模擬しなければならないと感じる場合、コードスニペットの重要な概念である依存関係を明らかに見つけたことになります。

この概念を明確にしてください!

あなたの場合、Bigqueryオブジェクトを取得し、その参照を変数に割り当てる必要があります。不明なコンセプトは、誰かがというようなオブジェクトを提供していることです。

interface BigqueryProvider { 
    Bigquery provide(Object options); 
} 
あなたも

Bigquery bigquery = Transport.newBigQueryClient(options).build(); 

は、あなたが今

private final BigqueryProvider bigqueryProvider; 

変数以下のインスタンスを追加文を持っているあなたのクラスで

と:

は、インタフェースとの明確なこの概念を作りますそれに応じてコンストラクタを変更します。私が作ったので、 finalは建設時に設定する必要があります。もちろん、コンストラクタを呼び出すコードも特定する必要があります。そのために、あなたはまた、デフォルトの実装が必要になります。そして、

final class DefaultBigqueryProvider implements BigqueryProvider { 
    @Override 
    public Bigquery provide(Object options) { 
     return Transport.newBigQueryClient(options).build(); 
    } 
} 

テストに今

Bigquery bigquery = bigqueryProvider.provide(options); 

に言及した上で割り当てを変更:あなたのテストでは、あなたが今、プロバイダインタフェースのためのテスト実装を提供することができます。模擬的なフレームワークは簡単にそれを行うことができます。また、あなたが選択したBigqueryオブジェクトを返すこともできます。それはそのクラスまたはサブクラスのオブジェクトであり、重要ではありません。

あなたのテストコードでは、あなたが完全に制御している模擬BigqueryProviderを提供することによってクラスをインスタンス化します。

関連する問題