2017-12-13 11 views
1

私はAndroid上でユニットテストを始めていますが、このクラスのbindTo()機能をテストしようとしたときにいくつかの問題が発生しました。私は私のViewKontrollerテストを模擬した場合関数内で設定されている匿名リスナーを使用してクラスをテストするにはどうすればよいですか?

class DataFlow<T> (produce: DataFlowProducer<T>): BaseDataFlow<T>(produce) { 
    var updateOnAttach: Boolean = true 

    fun bindTo(viewKontroller: ViewKontroller, updateImmediately: Boolean, updateUi: (data: T) -> Unit) { 
     this.updateUi = updateUi 
     if (updateImmediately) 
      flow() 
     viewKontroller.addLifecycleListener(object : Controller.LifecycleListener() { 
      override fun postAttach(controller: Controller, view: View) { 
       if (updateOnAttach) flow() 
      } 
      override fun preDestroyView(controller: Controller, view: View) { 
       viewKontroller.removeLifecycleListener(this) 
       [email protected] = null 
      } 
     }) 
    } 
} 

はまだラインviewKontroller.addLifecycleListener上のNPEでクラッシュ。

どうしたのですか?

+2

おそらくテストコードが助けになる – Moira

+0

申し訳ありませんが、今すぐコードをお持ちではありません。しかし、テストのメインラインは基本的に 'val dataflow = DataFlow {" test "} dataflow.bindTo(mock()、true、{result = it})' –

答えて

1

何がテストで確認したいことは、おそらく、少なくともこの:

  1. LifecycleListenerpreDestroyViewが他のViewKontroller何かに呼ばれたときonPostAttachViewKontroller何かが
  2. 起こることで呼び出されるとViewKontroller
  3. に追加しました起こる

したがって、コンストラクタに渡すは、リスナーが登録されているかどうかを "通知"する必要があります。また、そのリスナにメソッド呼び出しを委任する必要があります。

このような場合、テストのダブルオブジェクトに実際の機能が必要な場合は、モックを使用するよりも偽物を実装するのが最善です。

あなたの場合、ViewKontrollerを拡張するFakeViewKontrollerを実装し、模擬の代わりにテスト中のシステムに渡してください。

このクラスでは、LifecycleListenerが確実に追加されるようにする追加のメソッドを公開し、テストケースでそのリスナーのメソッドを呼び出すことができます。

+0

ありがとうございます!偽のクラスを使うのはとても便利です。しかし、コードについて考えると、それはちょうど悪い実装であり、 'bindTo'はViewKontrollerのメンバ関数でなければならず、ライフサイクルコールバックは後で簡単にテストできるDataFlowの関数に過ぎません。 –

+1

テストの結果としての優れたデザインの洞察力は、TDDの特徴です。 – Vasiliy

関連する問題