2012-04-19 13 views
9

Mam prosty przypadek testowy:Mockito - drwiące zajęcia z metod natywnych

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

Gdzie TableElement jest klasa GWT metodą insertRow zdefiniowane jako:

public final native TableRowElement insertRow(int index); 

Kiedy rozpocząć badanie Dostaję:

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) 

Co, jak sądzę, jest związane z rodzajem metody insertRow. Czy jest jakiś sposób obejścia takich metod z Mockito?

Odpowiedz

11

Samo Mockito nie wydaje się być w stanie wykpić natywnych metod zgodnie z tym Google Group thread. Jednak ty masz dwie opcje:

  1. zawinąć klasy TableElement w interfejsie i kpić, że interfejs do prawidłowego testowania że SUT nazywa owinięty insertRow(...) metoda. Wadą jest dodatkowy interfejs, który należy dodać (gdy projekt GWT powinien był to zrobić we własnym API) i narzuty, aby z niego korzystać. Kod dla interfejsu i konkretnej implementacji będzie wyglądać następująco:

    // 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. Korzystając Powermock i to Mockito API extension nazywa PowerMockito mock metody natywnej. Wadą jest to, że masz inną zależność do załadowania do swojego projektu testowego (jestem świadomy, że może to być problem z niektórymi organizacjami, w których musi być najpierw poddana audytowi zewnętrzna biblioteka, aby mogła być używana).

Osobiście pójdę z opcji 2, jako projekt GWT nie jest prawdopodobne, by zakończyć swoje zajęcia w interfejsach (i to jest bardziej prawdopodobne, że mają więcej metod natywnych, który musi być wyśmiewany) i robi to dla siebie zawijanie tylko natywnej metody to po prostu strata czasu.

+0

Niestety nie mam kontroli nad 'klasy TableElement' - należy ona do zewnętrznej biblioteki. Jednak rozszerzenie API Powermock Mockito wygląda bardzo interesująco, sprawdzę to. –

+0

Po zawinięciu cudzej rzeczy ** masz ** kontrolę. :-) To jest piękno owijaczy, [adapterów] (http://en.wikipedia.org/wiki/Adapter_pattern) lub [fasad] (http://en.wikipedia.org/wiki/Facade_pattern). – Spoike

+0

Bardzo dziękuję za bardzo dobrą i szczegółową odpowiedź. Zawijanie zadziała, a ja mogę go użyć w ostateczności, ale na mój gust zbyt wiele się kusi i komplikuje kod produkcyjny tylko do celów testowych :(. –

0

Jeśli ktoś się o to potknie: W międzyczasie (w May 2013) pojawiło się GwtMockito, które rozwiązuje ten problem bez narzutu PowerMocka.

Spróbuj

@RunWith(GwtMockitoTestRunner.class) 
public class MyTest { 

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