我有一个测试方法,开始遵循:
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可能实现多个接口,但同样不适用于类。如何测试上面显示的方法?
答案 0 :(得分:4)
Mockito使用Java 继承来替换类上方法的实现。但是,position
上的@Test public void contextMenuShouldWork() {
ContextMenuInfo info =
new AdapterView.AdapterContextMenuInfo(view, position, id);
systemUnderTest.onCreateContextMenu(menu, view, info);
/* assert success here */
}
似乎是字段,这意味着Mockito无法为您模拟它。
幸运的是,AdapterContextMenuInfo有AdapterContextMenuInfo
,所以你没必要
嘲笑它 - 你可以为测试创建一个并将其传递给你的方法。
class MyHelper {
/** Used for testing. */
int getPositionFromContextMenuInfo(ContextMenuInfo info) {
return ((AdapterContextMenuInfo) info).position;
}
}
如果你曾经遇到过无法直接模拟或实例化的类的模式,请考虑创建一个可以模拟的辅助类:< / p>
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);
// ...
}
}
现在您可以重构View以使用它:
/** 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 */
}
还有一个选项,涉及重构:
{{1}}
答案 1 :(得分:3)
可以使用mockito的extraInterfaces
选项
@Mock(extraInterfaces=AdapterView.AdapterContextMenuInfo.class)
ContextMenuInfo menuInfo
然后嘲笑它
Mockito.doReturn(1).when((AdapterView.AdapterContextMenuInfo)menuInfo).position
答案 2 :(得分:0)
为什么AdapterView.AdapterContextMenuInfo
中没有可以让你写info.getPosition()
的getter?如果你有,那么你可以模拟AdapterView.AdapterContextMenuInfo
,存根getPosition()
,然后将模拟传递给你正在测试的方法。