繁体   English   中英

使用Mockito将参数模拟对象转换为另一个对象

[英]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 继承来替换类上方法的实现。 但是,看起来positionAdapterContextMenuInfo上的一个字段 ,这意味着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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM