我正在尝试使用 Mockito 1.8.5 存根方法,但这样做会调用真正的方法实现(将 " 作为参数值),这会引发异常。
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 中的一个错误或已知限制,因为它应该支持这种情况(事实上,在大多数情况下确实支持它)。
最简单的方法是使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);
}
}
我的项目使用以下依赖项:
- jdk1.7.0_05
- JUNIT-4.10.jar
- 模拟全部-1.9.0.jar
- javassist-3.16.1-GA .jar
- 对象-1.2.jar
- 哈姆克雷斯特核心-1.1.jar