[英]Casting a parameter mock object to another object using Mockito
我有一个测试方法,开始遵循:
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
contextString = adapter.getItem(info.position);
/.../
}
我想用Mockito测试它,但如果我声明这样的menuInfo:
@Mock ContextMenuInfo menuInfo
然后我无法编译以下语句:
Mockito.when(menuInfo.position).thenReturn(1);
因为它对ContextMenuInfo
对象无效。 我不能将我的对象声明为AdapterView.AdapterContextMenuInfo
类,从那时起我在运行时遇到错误。
我知道在Mockito中,mock可能实现多个接口,但同样不适用于类。 如何测试上面显示的方法?
Mockito使用Java 继承来替换类上方法的实现。 但是,看起来position
是AdapterContextMenuInfo
上的一个字段 ,这意味着Mockito无法为您模拟它。
幸运的是,AdapterContextMenuInfo有一个公共构造函数 ,因此您不必模拟它 - 您只需为测试创建一个并将其传递给您的方法。
@Test public void contextMenuShouldWork() {
ContextMenuInfo info =
new AdapterView.AdapterContextMenuInfo(view, position, id);
systemUnderTest.onCreateContextMenu(menu, view, info);
/* assert success here */
}
如果您曾经因为无法直接模拟或实例化的类而陷入此模式 ,请考虑创建一个可以模拟的辅助类:
class MyHelper {
/** Used for testing. */
int getPositionFromContextMenuInfo(ContextMenuInfo info) {
return ((AdapterContextMenuInfo) info).position;
}
}
现在,您可以重构View以使用它:
public class MyActivity extends Activity {
/** visible for testing */
MyHelper helper = new MyHelper();
public void onCreateContextMenu(
ContextMenu menu, View v, ContextMenuInfo menuInfo) {
int position = helper.getPositionFromContextMenuInfo(menuInfo);
// ...
}
}
...然后在测试中模拟帮助器 。
/** This is only a good idea in a world where you can't instantiate the type. */
@Test public void contextMenuShouldWork() {
ContextMenuInfo info = getSomeInfoObjectYouCantChange();
MyHelper mockHelper = Mockito.mock(MyHelper.class);
when(mockHelper.getPositionFromContextMenu(info)).thenReturn(42);
systemUnderTest.helper = mockHelper;
systemUnderTest.onCreateContextMenu(menu, view, info);
/* assert success here */
}
还有一个选项,涉及一个重构:
public class MyActivity extends Activity {
public void onCreateContextMenu(
ContextMenu menu, View v, ContextMenuInfo menuInfo) {
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo) menuInfo;
onCreateContextMenuImpl(info.position);
}
/** visible for testing */
void onCreateContextMenuImpl(int position) {
// the bulk of the code goes here
}
}
@Test public void contextMenuShouldWork() {
systemUnderTest.onCreateContextMenuImpl(position);
/* assert success here */
}
可以使用mockito的extraInterfaces
选项
@Mock(extraInterfaces=AdapterView.AdapterContextMenuInfo.class)
ContextMenuInfo menuInfo
然后嘲笑它
Mockito.doReturn(1).when((AdapterView.AdapterContextMenuInfo)menuInfo).position
你为什么不在AdapterView.AdapterContextMenuInfo
中使用getter来编写info.getPosition()
? 如果你有,那么你可以模拟AdapterView.AdapterContextMenuInfo
,stub getPosition()
,然后将模拟传递给你正在测试的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.