2017-08-02 13 views
-2

私の質問は、元のメソッドと自分のテストパラメーターを呼び出すためにMockitoのdoAnswerを使用する方法です。問題を複雑にするために、パラメータの1つはプリミティブではありません。それはカスタムクラスです。複数のパラメータを持つMockitoを使用してセッターメソッドをモックする方法

を考えると、次の

public class EnvironmentQualityStatus { 
    public int environmentQuality = EnvironmentQualityStatus.NA; 
    public long cht = -1; 
    public int environmentSubType = -1; 
    public String engineer=""; 
    public int engineerType = -1; 
    public long timeStamp = 0; 
    public static final String version = "tpv1"; 

    EnvironmentQualityStatus(){} 

    EnvironmentQualityStatus(int environmentQuality, long cht, int environmentSubType, String engineer, int engineerType) { 
     this.environmentQuality = environmentQuality; 
     this.cht = cht; 
     this.environmentSubType = environmentSubType; 
     this.engineer = engineer; 
     this.engineerType = engineerType; 
     timeStamp = System.currentTimeMillis(); 
    } 

    @Override 
    public String toString() { 
     StringBuilder sb = new StringBuilder(); 
     sb.append("ts: "); 
     sb.append(timeStamp); 
     sb.append(", quality: "); 
     sb.append(EnvironmentQualityStatus.valueOf(environmentQuality)); 
     sb.append(", cht: "); 
     sb.append(cht); 
     sb.append(", type: "); 
     if (engineerType == Engineers.TYPE_CIVIL) { 
      sb.append(“civil”); 
     } else if (engineerType == Engineers.TYPE_INDUSTRIAL) { 
      sb.append(“industrial”); 
      if (!TextUtils.isEmpty(engineer)) { 
       sb.append(", Engineer: "); 
       sb.append(engineer); 
      } 
     } else { 
      sb.append("n/a"); 
     } 
     return sb.toString(); 
    } 
} 

クラスにいくつかのものを設定するには、上記の使用にコードを取ります。私がMockitoを使って嘲笑したいのは、この呼びかけ(そしてこのようなもの)です。

public class EnvironmentQuality { 
... 
public void updateEnvironmentQuality(EnvironmentQualityStatus eqStatus , 
             int environmentQuality ,int cht , String engineer, boolean notify){ 
     //set some stuff.... 
    } 
} 

私は、MockitoのdoAnswerを使用することがこれを行う正しい方法であることを理解しています。私はちょうど最後の部分をワイヤリングする方法を理解することができません。私は自分自身で呼び出された値を操作して、テスト実行時にそれらを使用するプログラムが自分の値を取得するようにします。私はMockitoドキュメントとこのトピックの周りのいくつかの記事を読んだが、それでも私には分かりません。

EnvironmentQuality environmentQuality = spy((EnvironmentQuality)EnvironmentQuality.getInstance(context)); 

    spy(environmentQuality).updateNetworkQuality(Mockito.any(com.something.internal.EnvironmentQualityStatus.class), anyInt(), anyInt(), anyString(), anyBoolean()); 
    doAnswer(new Answer<Void>() { 
     @Override 
     public Void answer(InvocationOnMock invocation) throws Throwable { 

      //This is an example of how to spy the parameters that were passed. 
      EnvironmentQualityStatus status = (EnvironmentQualityStatus)invocation.getArguments()[0]; 

      int environmentQuality = (int)invocation.getArguments()[1]; 
      int cht = (int)invocation.getArguments()[2]; 
      String engineer = (String)invocation.getArguments()[3]; 
      boolean notify = (boolean)invocation.getArguments()[4]; 

      //But how to customize the parameters so that every time updateEnvironmentQuality(...) is called, a test can customize the params and dynamically influence the values. 
      return null; 
     } 
    }).when(environmentQuality).updateEnvironmentQuality(Mockito.any(com.something.internal.EnvironmentQualityStatus.class), anyInt(), anyInt(), anyString(), anyBoolean()); 
+1

doAnswer内でEnvironmentQualityStatusパラメータを更新することは可能ですが、残りは変更できません。 –

+1

なぜ-1?私はその質問とあなたの答えが誰かに同じものを明らかにすることができると思います。 –

+1

あなたの質問は私には分かりません。スタブ付きメソッドの実際のバージョンも同様に呼び出すが、パラメータの値は変更したいと言っていますか?私はMockitoがこれを現在行っているとは思わないが、あなたは機能要求を入れることができる。 –

答えて

1

他の値を指定してメソッドを呼び出すとします。 the documentationInvocationOnMockにチェックすることで、Methodと呼び出されたObjectを取得する方法を調べることができます。したがって、これは変更するのが非常に簡単なはずです:

@Override 
    public Void answer(InvocationOnMock invocation) throws Throwable { 
     Object callingObject = invocation.getMock(); 
     Method method = invocation.getMethod(); 
     method.invoke(callingObject, /* arguments... */); 
     return null; 
    } 
+0

私はこれに追加したいと思います。私がやっているようにメソッドをプロキシしようとしている場合、私たちは再帰呼び出しの状況に陥っていました。独自のパラメータでメソッドを呼び出すと、Answerに戻ります。そこで、これを回避するには、リフレクションを使用して、セッターメソッドが設定していたメンバー変数を取得します。したがって、(私たちの)結果は、再帰の問題なしで同じです。あなたのマイレージは異なる場合があります。 –

+0

これはテストしましたか?私はそれが動作するかどうかは分かりません。 'Method'の' invoke'メソッドのJavadocによれば、Java言語仕様第2版の15.12.4.4節に書かれているように、動的メソッド参照を使って呼び出されます;特に、ランタイムタイプのターゲットオブジェクトが発生します... "_これは、スタブされたオブジェクトに対してメソッドを再度呼び出すだけであることを意味します。したがって、あなたの 'answer'メソッドは、あなたのスタックがオーバーフローするまで、それ自身を繰り返し呼び出します。 –

関連する問題