我对Mockito有点陌生,我想知道如何存根一个get/set对。
例如
public interface Dummy {
public String getString();
public void setString(String string);
}
如何使它们正常运行:如果我在测试中的某个地方调用setString("something");
我希望getString()
返回"某些东西"。这是否可行,或者有更好的方法来处理此类案件?
我还希望 getter 返回最近 setter 调用的结果。
拥有
class Dog
{
private Sound sound;
public Sound getSound() {
return sound;
}
public void setSound(Sound sound) {
this.sound = sound;
}
}
class Sound
{
private String syllable;
Sound(String syllable) {
this.syllable = syllable;
}
}
我使用以下方法将二传手连接到吸气器:
final Dog mockedDog = Mockito.mock(Dog.class, Mockito.RETURNS_DEEP_STUBS);
// connect getter and setter
Mockito.when(mockedDog.getSound()).thenCallRealMethod();
Mockito.doCallRealMethod().when(mockedDog).setSound(Mockito.any(Sound.class));
我可以想到三种可能的方法。
-
不要直接在应用程序中使用
HttpServletRequest
;为它创建一个包装类,并为包装类提供一个接口。 无论您当前在应用程序中使用HttpServletRequest
的任何地方,请改用该接口。 然后在测试中,有此接口的替代实现。 然后,你根本不需要Mockito模拟。 -
在测试类中有一个字段,用于存储已将
String
设置为的值。 制作两个莫西托Answer
对象;一个在调用getString
时返回此字段的值,另一个在调用setString
时设置此字段的值。 以通常的方式进行模拟,并存根以使用这两个答案。 -
创建一个抽象类(可以是测试类的静态内部类),该类实现
HttpServletRequest
接口,但具有要设置的字段,并定义 getter 和 setter。 然后模拟抽象类,并将Mockito.CALLS_REAL_METHODS作为默认答案传入。 当你在模拟上调用吸气手或二传手时,真正的方法就会启动,这就是你想要的行为。
希望这三种选择之一能够满足您的需求。
我发现这工作正常:
doAnswer(answer -> when(dummy.getString()).thenReturn((String) answer.getArguments()[0]))
.when(dummy).setString(any());
我必须使用doAnswer(..)。when(..),因为二传手是一个无效的方法。当使用对象调用 setter 时,getter 将被设置为使用相同的对象进行响应。
当你有一个接口但没有实现时非常有用。
在这种特殊情况下,对于HttpServletRequest stubbing,我强烈建议使用Spring-Mock框架:(http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/mock/web/package-summary.html)
它具有用于基于Web的操作的内置模拟。
否则,请使用答案为模拟对象定义自己的响应 (http://mockito.googlecode.com/svn/branches/1.8.5/javadoc/org/mockito/stubbing/Answer.html)
我遇到了这个问题,但不想接受接受的答案,因为这样做会停止嘲笑我豆子中的所有 getter 和 setter。我想要的只是为单个 getter/setter 对创建存根,而不是全部。因此,我使用了以下代码。
@Mock
private Dummy mockDummy;
private final MutableObject<String> stringWrapper = new MutableObject<>();
public TestClass() {
MockitoAnnotations.initMocks(this);
doAnswer(invocationOnMock -> {
String injectedString = (String)invocationOnMock.getArguments()[0];
TestClass.this.stringWrapper.setValue(injectedString);
return null;
}).when(this.mockDummy).setString(any());
when(this.mockDummy.getString()).thenAnswer(
invocationOnMock -> TestClass.this.stringValue.getValue());
}
第一个 lambda 实现了Answer<Void>
匿名类的answer()
方法。因此,每当受测代码执行 setter 方法时,该 setter 的存根都会将其记录到 MutableObject
帮助程序对象中。然后,getter 实现可以返回设置的此记录值。