2016-09-29 8 views
0

InvocationContextをパラメータとしてメソッドのユニットテストを作成しようとしています。より具体的には、メソッドのシグネチャと本質があります。ユニットテスト用のInvocationContextのインテンスを取得する方法

@AroundInvoke 
public Object autoLogMethodCall(final InvocationContext context) throws Exception { 

    String className = context.getClass().getSimpleName(); 
    String packageName = context.getClass().getPackage().getName(); 
    String methodName = context.getMethod().getName(); 

    // Some logging stuff that is the target of actual testing 
} 

ご覧のとおり、特定のメソッド呼び出しの基本的なロギングに使用するインターセプタメソッドです。

次に、ログされたメッセージが適切にフォーマットされることをテストするユニットテストがあります。しかし問題は、私がInvocationContextのインスタンスを作成してテスト用のパラメータとして渡せないことです。

私は以下の模擬試しを試みました。

しかし、動作しません。
原因:

Tests in error: AutoLoggingTest.testAutoLogger:25 » MissingMethodInvocation.
when() requires an argument which has to be 'a method call on a mock'.).

適切にモックを行う方法上の任意のアドバイスはありますか?

答えて

0

これは、何か考え直す必要がありました。 mockされたInvocationContextとのいくつかの混合コンテンツが必要です。そこで我々は、Iを加え、テストクラス自体に次のように変更し、モックInvocationContextオブジェクトにテストクラス自体を提供することができる:

​​

はまた、私はそれがwasnとしてI「はMyLogger」のコードを提供しなければならない実現しましたテストのために実装するのは非常に簡単です。

// Logger = org.apache.logging.log4j.Logger 
// ExtendedLoggerWrapper = org.apache.logging.log4j.spi.ExtendedLoggerWrapper 
@SuppressWarnings("serial") 
protected class MyLogger extends ExtendedLoggerWrapper implements Logger { 
    private List<String> messages; 

    public MyLogger() { 
     super(null, null, null); 
     this.clearMessages(); 
    } 

    // The actual log calls need to get stored to store the messages + prevent from NullPointerExceptions 
    @Override 
    public void trace(String msg) { 
     messages.add(msg); 
    } 

    // The actual log calls need to get stored to store the messages + prevent from NullPointerExceptions 
    @Override 
    public Object exit(Object obj) { 
     messages.add("Exited with: " + obj); 
     return obj; 
    } 

    public List<String> getMessages() { 
     return this.messages; 
    } 

    public void clearMessages() { 
     messages = new ArrayList<>(); 
    } 

    /** 
    * You need to override all the method calls used to prevent NullPointerExceptions. 
    * 
    * @return <code>True</code> always, as required so in test. 
    */ 
    @Override 
    public boolean isTraceEnabled() { 
     return true; 
    } 
} 

、元のロギングクラスに必要ないくつかのマイナーなリファクタリングがあったことから、それは次のようになります。

public abstract class AutoLoggingUtility { 

    private static final String logEntryTemplate = "Call to: %1$s#%2$s"; 
    private static final String logExitTemplate = "'%1$s' call duration: %2$s ms"; 

    public AutoLoggingUtility() { 

    } 

    @AroundInvoke 
    public Object autoLogMethodCall(final InvocationContext context) throws Exception { 
    // Note the methods Overridden in MyLogger 
    if (this.getLogger().isTraceEnabled()) { 
     String methodName = null; 
     String className = null; 
     try { 
      Method method = context.getMethod(); 
      methodName = method.getName(); 
      // Contains package 
      className = context.getMethod().getDeclaringClass().getName(); 
      } catch (Exception e) { 
       // May not crash 
       methodName = "?method?"; 
       className = "?class?"; 
      } 
      Object[] args1 = { className, methodName }; 
      String logMsg = String.format(getLogentrytemplate(), args1); 
      this.getLogger().trace(logMsg); 

      long startTime = System.currentTimeMillis(); 
      try { 
      return this.getLogger().exit(context.proceed()); 
      } finally { 
      Object[] args2 = { methodName, System.currentTimeMillis() - startTime }; 
      logMsg = String.format(getLogexittemplate(), args2); 
      this.getLogger().trace(logMsg); 
     } 
    } else { 
     // mocked 
     return context.proceed(); 
    } 

    /** 
    * Forces each extending class to provide their own logger. 
    * 
    * @return The logger of the extending class to direct the messages to correct logging context. 
    */ 
    abstract Logger getLogger(); 
} 

AutoLoggingUtilityImplForTestingは」単純にインスタンスを保持するために「AutoLoggingUtility」を拡張MyLoggerです。

Summarum:
トリック「はgetMethod()メソッド」が呼び出されたときに返すモックオブジェクトのテストクラスのメソッド「methodForLoggingTesting」のインスタンスを提供することです。 = >余分なものをモックしようとする必要はありません。

関連する問題