2012-04-19 24 views
9

Tôi có trường hợp thử nghiệm đơn giản:Mockito - chế giễu các lớp học với phương pháp tự nhiên

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

đâu TableElement là GWT lớp học với phương pháp insertRow định nghĩa là:

public final native TableRowElement insertRow(int index); 

Khi tôi khởi động thử nghiệm tôi nhận được:

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) 

Như tôi tin là có liên quan với phương thức insertRow là gốc. Có cách nào hay cách nào khác để giả lập các phương pháp như vậy với Mockito?

Trả lời

11

Bản thân Mockito dường như không thể thử phương pháp gốc theo số Google Group thread này. Tuy nhiên bạn có hai lựa chọn:

  1. Bó lớp TableElement trong một giao diện và thử giao diện đó để kiểm tra đúng rằng SUT của bạn gọi là bọc insertRow(...) phương pháp. Hạn chế là giao diện bổ sung mà bạn cần phải thêm (khi dự án GWT nên thực hiện điều này trong API của chính họ) và chi phí để sử dụng nó. Mã cho giao diện và thực hiện cụ thể sẽ trông như thế này:

    // 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. Sử dụng Powermock và nó Mockito API extension gọi PowerMockito để thử phương pháp tự nhiên. Nhược điểm là bạn có một phụ thuộc khác để tải vào dự án thử nghiệm của bạn (tôi biết điều này có thể là một vấn đề với một số tổ chức mà thư viện của bên thứ ba phải được kiểm tra đầu tiên để được sử dụng).

Cá nhân tôi muốn đi với phương án 2, như dự án GWT là không có khả năng để quấn lớp của mình trong giao diện (và nó có nhiều khả năng họ có phương pháp tự nhiên hơn mà cần phải được chế giễu) và làm nó cho chính mình để chỉ quấn một cuộc gọi phương pháp bản địa chỉ là lãng phí thời gian của bạn.

+0

Đáng tiếc là tôi đã không kiểm soát lớp 'TableElement' - nó thuộc về thư viện bên ngoài. Tuy nhiên, phần mở rộng API Powermock Mockito trông rất thú vị, tôi sẽ kiểm tra nó. –

+0

Khi bạn quấn đồ của người khác thì ** bạn ** có quyền kiểm soát. :-) Đó là vẻ đẹp của hàm bao, [adapter] (http://en.wikipedia.org/wiki/Adapter_pattern), hoặc [façades] (http://en.wikipedia.org/wiki/Facade_pattern). – Spoike

+0

Cảm ơn rất nhiều câu trả lời rất tốt và chi tiết. Bao bì sẽ hoạt động và tôi có thể sử dụng nó như một phương sách cuối cùng nhưng đối với khẩu vị của tôi, nó quá khắt khe và làm phức tạp mã sản xuất chỉ cho các mục đích thử nghiệm: ( –

0

Trong trường hợp bất kỳ ai khác tình cờ về điều này: Trong khi chờ đợi (trong May 2013) GwtMockito bật lên, giải quyết được vấn đề này mà không cần phí của PowerMock.

Hãy thử điều này

@RunWith(GwtMockitoTestRunner.class) 
public class MyTest { 

    @Test 
    public void test() throws Exception{ 
     TableElement table = mock(TableElement.class); 
     table.insertRow(0); 
    } 
} 
Các vấn đề liên quan