简体   繁体   English

Mockito - 使用本机方法模拟类

[英]Mockito - mocking classes with native methods

I have simple test case: 我有简单的测试用例:

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

Where TableElement is GWT class with method insertRow defined as: 其中TableElement是GWT类,方法insertRow定义为:

public final native TableRowElement insertRow(int index);

When I launch test I'm getting: 当我开始测试时,我得到:

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)

Which as I believe is related with insertRow method being native. 我相信哪个与insertRow方法有关。 Is there any way or workaround to mock such methods with Mockito? 有没有办法或解决方法来模拟Mockito的这些方法?

Mockito itself doesn't seem to be able to mock native methods according to this Google Group thread . Mockito本身似乎无法根据此Google Group线程模拟本机方法。 However you do have two options: 但是,您有两个选择:

  1. Wrap the TableElement class in an interface and mock that interface to properly test that your SUT calls the wrapped insertRow(...) method. TableElement类包装在一个接口中并模拟该接口以正确测试您的SUT调用包装的insertRow(...)方法。 The drawback is the extra interface that you need to add (when GWT project should've done this in their own API) and the overhead to use it. 缺点是您需要添加额外的接口(当GWT项目应该在他们自己的API中完成此操作时)以及使用它的开销。 The code for the interface and the concrete implementation would look like this: 接口的代码和具体实现如下所示:

     // 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. Use Powermock and it's Mockito API extension called PowerMockito to mock the native method. 使用Powermock和它的名为PowerMockitoMockito API扩展来模拟本机方法。 The drawback is that you have another dependency to load into your test project (I'm aware this may be a problem with some organizations where a 3rd party library has to be audited first in order to be used). 缺点是您有另一个依赖项加载到您的测试项目(我知道这可能是一些组织的问题,其中第三方库必须首先被审计才能被使用)。

Personally I'd go with option 2, as GWT project is not likely to wrap their own classes in interfaces (and it is more likely they have more native methods that needs to be mocked) and doing it for yourself to only wrap a native method call is just waste of your time. 我个人会选择2,因为GWT项目不可能在接口中包装自己的类(并且它更可能有更多需要模拟的本机方法)并且自己做它只包装本机方法打电话只是浪费你的时间。

In case anybody else stumbles about this: In the meantime (in May 2013 ) GwtMockito turned up, which solves this problem without PowerMock's overhead. 万一其他人偶然发现:在此期间( 20135月GwtMockito出现了,这解决了这个问题,没有PowerMock的开销。

Try this 试试这个

@RunWith(GwtMockitoTestRunner.class)
public class MyTest {

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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