2012-08-16 9 views
19

Mockito 1.8.5を使用してメソッドをスタブしようとしていますが、これを行うと例外をスローする実際のメソッド実装。パッケージの保護されたメソッドをスタブしようとすると実際のメソッド実装を呼び出すMockitoモック

package background.internal; //located in trunk/tests/java/background/internal 

public class MoveStepTest { 

    @Test 
    public void testMoveUpdate() { 
     final String returnValue = "value"; 
     final FileAttachmentContainer file = mock(FileAttachmentContainer.class); 
     doReturn(returnValue).when(file).moveAttachment(anyString(), anyString(), anyString()); 
     //this also fails 
     //when(file.moveAttachment(anyString(), anyString(), anyString())).thenReturn(returnValue); 

     final AttachmentMoveStep move = new AttachmentMoveStep(file); 
     final Action moveResult = move.advance(1, mock(Context.class)); 
     assertEquals(Action.done, moveResult); 
    } 
} 

私が模倣しようとしている方法は、このように見えます。最終的なメソッドやクラスはありません。

package background.internal; //located in trunk/src/background/internal 


    public class FileAttachmentContainer { 
     String moveAttachment(final String arg1, final String arg2, final String arg3) 
       throws CustomException { 
      ... 
     } 

     String getPersistedValue(final Context context) { 
      ...  
     } 
    } 

とクラス私はこのようなモックルックスを渡している:

package background.internal; //located in trunk/src/background/internal 
public class AttachmentMoveStep { 

    private final FileAttachmentContainer file; 

    public AttachmentMoveStep(final FileAttachmentContainer file) { 
     this.file = file;   
    } 

    public Action advance(final double acceleration, final Context context) { 
     try { 
      final String attachmentValue = this.file.getPersistedValue(context); 
      final String entryId = this.file.moveAttachment(attachmentValue, "attachment", context.getUserName()); 

      //do some other stuff with entryId 
     } catch (CustomException e) { 
      e.log(context); 
     }  
     return Action.done; 
    } 
} 

実際の実装が呼び出されると、どのように私はそれを防ぐことができます原因は何?

+0

実際にテストを実行しているコードを追加できますか? – jhericks

+1

'FileAttachmentContainer'または' moveAttachment() 'メソッドは最終的ですか? Mockitoは最終的な方法をモックできません。 –

+0

実際にmoveAttachmentはanyString()の値で呼び出されますか? – markus

答えて

19

あなたが模倣している方法には、Mockitoコードからアクセスできません。

テストコードとテスト対象のコードが同じパッケージになっているため、コンパイラではモックをそのように設定できますが、実行時にMockitoライブラリはmoveAttachmentにアクセスする必要がありますが、場合。これは、そのケースをサポートする必要があるため、Mockitoのbugまたはknown limitationのように見えます(実際はほとんどの場合サポートしています)。

最も簡単なことは、moveAttachmentをパブリックメソッドにすることです。それがオプションでない場合は、最初にあなたがそれを嘲笑したいかどうか質問してください。実際のメソッドが呼び出されるとどうなりますか?

最後の選択肢はを使用してmoveAttachmentメソッドをプライベートメソッドとして扱い、そのように偽装します。

+0

これは問題のようです。それはまた、他の人々がそれに遭遇したように見えます:http://code.google.com/p/mockito/issues/detail?id=127ありがとう –

+0

これは正しくありません。一般的に、Mockitoはパッケージのプライベートメソッドを問題なくモックできます。このバグは、OSGi /密封されたジャーまたはそれに類するものの問題であるようです。 –

+0

@ Arendv.Reinersdorff、それが真実なら、PowerMockはまだそのトリックをしますか?もしそうなら、私は自分の答えを変えて、その "理由"の部分をよりよく反映させようとします。 – jhericks

0

私は受け入れた回答に同意しません。

私はあなたの環境に関する詳細を提供しなければならないと思います。私はあなたの問題を再現できません。私は、Mavenプロジェクトに次のコードを記述します。

package background.internal; //located in src/main/java 

public class FileAttachmentContainer { 
    String moveAttachment(String arg1, String arg2, String arg3) { 
     throw new IllegalStateException(); 
    } 

    String getPersistedValue(Context context) { 
     throw new IllegalStateException(); 
    } 
} 

package background.internal; 

public class AttachmentMoveStep { 

    private FileAttachmentContainer file; 

    public AttachmentMoveStep(FileAttachmentContainer file) { 
     this.file = file; 
    } 

    public Action advance(double acceleration, Context context) { 
     String attachmentValue = file.getPersistedValue(context); 
     file.moveAttachment(attachmentValue, "attachment", context.getUserName()); 
     return Action.done; 
    } 
} 

と、次のテストパス

package background.internal; //located in src/test/java 

import static org.junit.Assert.assertEquals; 
import static org.mockito.Matchers.anyString; 
import static org.mockito.Mockito.doReturn; 
import static org.mockito.Mockito.mock; 

import org.junit.Test; 

public class MoveStepTest { 

    @Test 
    public void testMoveUpdate() { 
     String returnValue = "value"; 
     FileAttachmentContainer file = mock(FileAttachmentContainer.class); 
     doReturn(returnValue).when(file).moveAttachment(anyString(), anyString(), anyString()); 
     //this also works 
     //when(file.moveAttachment(anyString(), anyString(), anyString())).thenReturn(returnValue); 

     AttachmentMoveStep move = new AttachmentMoveStep(file); 
     Action moveResult = move.advance(1, mock(Context.class)); 
     assertEquals(Action.done, moveResult); 
    } 
} 

私のプロジェクトは、以下の依存関係を使用します。

  • をjdk1.7.0_05
  • JUnitの-4.10.jar
  • mockito-全1.9.0.jar
  • Javassistの-3.16.1-GA.jar
  • objenesis-1.2.jar
  • hamcrestコア-1.1.jar
+3

これはまったく答えはありません。質問者が問題を抱えている理由を理解できないと言うだけです。疑問は、「実際の実装を呼び起こす原因は何か、どうすればそれを防ぐことができるのか」私は「どうしたらそれを防ぐことができますか?」という部分に答えましたが、「原因は何か」という部分だけを推測しました。この答えはどちらもありません。この回答はちょうどそれが働くべきであると言います、なぜあなたはそれがなぜそうしないのか分かりません。 – jhericks

+0

@ jhericks、あなたが正しいです、私はなぜ、私にとってはこれは問題です。私は物事の底に立ち、問題の根本的な原因を見つけなければならないと思う。回避策を提供するだけではありません。 – gontard

+0

@gontard 2つの別々の瓶にコンパイルしましたか? 1つはテストと実装されたものですか? –

関連する問題