Mockito 通过使用 Java继承来替换类上方法的实现来工作。但是,它看起来像是position
一个字段on 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;
}
}
现在您可以重构您的视图以使用它:
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 */
}