2016-10-27 14 views
0

私は非常に結合したコードを持つチームプロジェクトに取り組んでいます。私はユニットテストのカバレッジを高めるためにしようとしていると私は次のシナリオに直面しました:Dagger2 + Mockito:ユニットの使い方このシナリオをテストしますか?

class Foo { 
    static void methodA() { 
     Bar b = new Bar(); 
     b.getContent(); 
    } 
} 

class Bar { 

    @Inject 
    DBAcessor mDBAcessor; 

    Bar() { 
     Dagger2.getInjector().inject(this); 
    } 

    public Object getContent() { 
     mDBAcessor.fetchData(); 
    } 

} 

私はそれを渡さずにそれを行うことが可能である場合しかし、私は知らないが、ユニットテストmethodA()にしたいDBAcessorオブジェクトをコンストラクタ経由でBar()クラスに追加します。 Barはプロジェクト全体で広く使用されているPOJOモデルでなければなりません。そのため、コンストラクタを変更して他の多くのクラスに影響を与えることをお勧めしますか?このシナリオにどのようにアプローチすればよいですか?

答えて

1

これは間違ったデザインです。

コンストラクタにアクセスできる場合は、クラス依存関係をコンストラクタに渡します。それは本当に単体テストを楽にします。クラスBarはなります。Componentで宣言さ

class Bar() { 

    @Inject DBAcessor mDBAcessor; 

    Bar (DBAcessor dbAcessor) { 
     this.mDBAcessor = dbAcessor; 
    } 

    public Object getContent() { 
     mDBAcessor.fetchData(); 
    } 
} 

Dagger2メソッドは、オブジェクトの内部で使用する必要がありますが、コンストラクタ(ActivityまたはFragment)へのアクセスを持っていません。

その後は何もそれをやってからあなたを妨げるものはない:

DBAccessor dbAccessor = Mockito.mock(DBAccessor.class); 
Bar bar = new Bar(dbAccessor); 
bar.getContent(); 
verify(bar, times(1)).fetchData(); 

あなたは本当にこのような設計に固執する必要がある場合Dagger2が必要Applicationオブジェクトに依存して、そしてあなたは、このようなオブジェクト上でユニットテストをすることはできませんContext、ユニットテストではエミュレートできません。テストをandroidTestと書き、適切なActivityを作成し、Barオブジェクトを取り出してテストします。

+0

この部分で詳細を教えてください。 "Componentで宣言されたDagger2メソッドは、コンストラクタ(ActivityまたはFragment)にアクセスできないオブジェクトの内部でのみ使用されます。" –

+1

Dagger2には「コンポーネント」という用語があります。たぶん 'Application'や' Activity'やカスタムのものかもしれません。スコープと考えてください。もしあなたが 'Component'の中に' inject'メソッドを宣言しなければ、コードで 'inject(this)'を使うことができないので、 'Dagger2'はあなたのオブジェクトをあなたが望むクラス('コンストラクタにアクセスできます)。 –

+0

私は、高レベルのクラスから低レベルのクラスへの依存関係を引き続き渡す必要があることを理解しています。しかし、私がクラス 'Bar'でそれをやってみると、' static'メソッドしかないので 'Foo'クラスの' inject'をどこで呼び出すべきですか? –

関連する問題