Mockito - 使用本机方法模拟类



我有一个简单的测试用例:

@Test
public void test() throws Exception{
       TableElement table = mock(TableElement.class);
       table.insertRow(0);
}

其中 TableElement 是 GWT 类,方法insertRow定义为:

public final native TableRowElement insertRow(int index);

当我启动测试时,我得到:

java.lang.UnsatisfiedLinkError: com.google.gwt.dom.client.TableElement.insertRow(I)Lcom/google/gwt/dom/client/TableRowElement;
    at com.google.gwt.dom.client.TableElement.insertRow(Native Method)

我相信这与插入行方法的本机有关。有什么方法或解决方法可以用 Mockito 模拟这些方法吗?

根据这个 Google Group 线程,Mockito 本身似乎无法模拟本机方法。但是,您有两个选择:

  1. TableElement 类包装在接口中并模拟该接口,以正确测试 SUT 是否调用包装的 insertRow(...) 方法。缺点是您需要添加额外的接口(当 GWT 项目应该在他们自己的 API 中完成此操作时)以及使用它的开销。接口和具体实现的代码如下所示:

    // the mockable interface
    public interface ITableElementWrapper {
        public void insertRow(int index);
    }
    // the concrete implementation that you'll be using
    public class TableElementWrapper implements ITableElementWrapper {
        TableElement wrapped;
        public TableElementWrapper(TableElement te) {
            this.wrapped = te;
        }
        public void insertRow(int index) {
            wrapped.insertRow(index);
        }
    }
    // the factory that your SUT should be injected with and be 
    // using to wrap the table element with
    public interface IGwtWrapperFactory {
        public ITableElementWrapper wrap(TableElement te);
    }
    public class GwtWrapperFactory implements IGwtWrapperFactory {
        public ITableElementWrapper wrap(TableElement te) {
            return new TableElementWrapper(te);
        }
    }
    
  2. 使用Powermock,它是名为PowerMockito的Mockito API扩展来模拟本机方法。缺点是您需要将另一个依赖项加载到测试项目中(我知道这可能是某些组织的问题,其中必须首先审核第三方库才能使用)。

就我个人而言,我会选择选项 2,因为 GWT 项目不太可能将自己的类包装在接口中(而且他们更有可能有更多需要模拟的本机方法),并且自己只包装本机方法调用只是浪费您的时间。

万一其他人对此感到困惑:与此同时(2013 年 5 月),GwtMockito 出现了,它解决了这个问题,而没有 PowerMock 的开销。

试试这个

@RunWith(GwtMockitoTestRunner.class)
public class MyTest {
    @Test
    public void test() throws Exception{
        TableElement table = mock(TableElement.class);
        table.insertRow(0);
    }
}

相关内容

  • 没有找到相关文章

最新更新