Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

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. Is there any way or workaround to mock such methods with Mockito?

like image 702
Piotr Sobczyk Avatar asked Apr 19 '12 07:04

Piotr Sobczyk


1 Answers

Mockito itself doesn't seem to be able to mock native methods according to this Google Group thread. 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. 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. 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. 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.

like image 82
Spoike Avatar answered Sep 17 '22 17:09

Spoike