Mockito 1.8.5を使用してメソッドをスタブしようとしていますが、そうすると実際のメソッド実装(parm値として ""を使用)が呼び出され、例外がスローされます。
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;
}
}
実際の実装が呼び出される原因は何ですか?どのように防ぐことができますか?
モックしているメソッドは、Mockitoコードからアクセスできません。
テストコードとテスト対象のコードは同じパッケージにあるため、コンパイラによりモックをそのように設定できますが、実行時にMockitoライブラリはmoveAttachment
にアクセスしようとしなければなりませんが、あなたの場合。これは、Mockitoでは bug または 既知の制限 のように見えます(実際に、ほとんどの場合サポートしています)。
最も簡単なことは、moveAttachment
をパブリックメソッドにすることです。それが選択肢でない場合は、まずそれをモックするかどうかを最初に質問します。実際のメソッドが呼び出されるとどうなりますか?
最後のオプションは、 PowerMock を使用してmoveAttachment
メソッドをプライベートメソッドとして扱い、そのようにモックすることです。
受け入れられた回答に同意しません。
環境についてもっと詳しく説明する必要があると思います。問題を再現できません。 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);
}
}
私のプロジェクトは次の依存関係を使用します。