11

我有简单的测试用例:

@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)

我认为这与本机的 insertRow 方法有关。有什么方法或解决方法可以用 Mockito 模拟这些方法吗?

4

2 回答 2

12

根据这个Google Group thread 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和调用它的Mockito API 扩展PowerMockito来模拟本机方法。缺点是您有另一个依赖项要加载到您的测试项目中(我知道这可能是某些组织的问题,其中必须首先审核第 3 方库才能使用)。

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

于 2012-04-19T07:51:38.500 回答
0

以防其他人对此感到困惑:与此同时(2013 年5 月GwtMockito出现了,它在没有 PowerMock 开销的情况下解决了这个问题。

尝试这个

@RunWith(GwtMockitoTestRunner.class)
public class MyTest {

    @Test
    public void test() throws Exception{
        TableElement table = mock(TableElement.class);
        table.insertRow(0);
    }
}
于 2016-08-08T15:35:45.647 回答