2015-06-05 15 views
5

EDIT: Cuối cùng tôi đã tạo một issue về dự án Mockito github.Mockito returnsFirstArg() không làm việc với arg đầu tiên generic

Tôi đang cố gắng để thử phương pháp gõ getNameElement của Interface RoomGeneralService để trả lại arg đầu tiên, sử dụng Mockito AdditionalAnswers.returnsFirstArg chức năng:

Interface để thử:

interface PrimaryKeyElement<T> { 
    public String getNameElement(T primaryKey); 
} 

interface RoomGeneralService extends PrimaryKeyElement<String> { 
    // ... 
} 

thử nghiệm của tôi (lưu ý hàng nhập khẩu)

import static org.mockito.AdditionalAnswers.returnsFirstArg; 
import static org.mockito.Matchers.any; 
import static org.mockito.Matchers.anyString; 
import static org.mockito.Mockito.when; 

@RunWith(PowerMockRunner.class) 
public class SampleTest { 

    @Mock 
    RoomGeneralService roomGeneralService; 

    @Test 
    public void testFoo() throws Exception { 
     when(roomGeneralService.getNameElement(anyString())).thenAnswer(returnsFirstArg()); 
     //... 
    } 
} 

Ngoài ra tôi đã thử với các kết hợp khác, nhưng không thành công cho đến nay:

when(roomGeneralService.getNameElement(Matchers.<String>any())).thenAnswer(returnsFirstArg()); 
doAnswer(returnsFirstArg()).when(roomGeneralService.getNameElement(anyString())); 
doReturn(returnsFirstArg()).when(roomGeneralService.getNameElement(anyString())); 

Lỗi nhận:

Lý do cho lỗi này có thể là: 1. muốn tranh luận vị trí không đúng. 2. Câu trả lời được sử dụng trên sự tương tác sai.

Vị trí của đối số truy nã là 0 và các chỉ số tham số có thể cho phương pháp này là: [0] Object

Cách giải quyết:

Tôi biết tôi có thể tạo ra câu trả lời của riêng tôi, và trong thực tế nó làm việc tốt nếu thay vì sử dụng returnFirstArg() tôi làm điều gì đó như thế này:

when(roomGeneralService.getNameElement(anyString())).thenAnswer(new Answer<String>() { 
    @Override 
    public String answer(InvocationOnMock invocation) throws Throwable { 
     return (String) invocation.getArguments()[0]; 
    } 
}); 

Nhưng tôi sẽ sử dụng returnFirstArg() như trong phần còn lại của các bài kiểm tra của tôi (kiểm tra trông sạch hơn), cũng như chế nhạo đang làm việc tốt nếu phương pháp getNameElement sẽ nhận được String thay vì T arg.

Cảm ơn sự giúp đỡ.

Trả lời

0

Cuối cùng tôi quyết định mở một vấn đề (#1071) về dự án github Mockito và nó đã được cố định trong phiên bản 2.8.29 (Xem chính thức changelog) Nhờ đội Mockito để giải quyết nó một cách nhanh chóng!

Trích dẫn @ChristianSchwarz, đây là một vấn đề giải thích:

Mockito kiểm tra xem loại đối số là phù hợp với kiểu trả về để thực hiện một lạm dụng ot API thời gian sớm nhất có thể nhìn thấy. Trong trường hợp này đối tượng kiểu đối tượng được suy ra từ loại T chung, do loại xóa. Vì Đối tượng không phải là loại phụ của Chuỗi Mockito, hãy ném ra ngoại lệ mà bạn nhìn thấy.

Giải pháp: Sự cố có thể được khắc phục bằng cách suy ra loại đối số của ví dụ đối số thực tế . Trong trường hợp kiểu đối số là nguyên thủy hoặc arg là null Mockito phải dự phòng và sử dụng loại được cung cấp bởi chữ ký phương thức .

1

Dường như Mockito không đủ thông minh để suy ra rằng loại tham số sẽ được ràng buộc với String trong giao diện con được tham số hóa.

Bạn có thể ghi đè phương pháp này trong subinterface

interface RoomGeneralService extends PrimaryKeyElement<String> { 
    @Override 
    public String getNameElement(String primaryKey); 
} 

Mockito sẽ không phải đoán. Nó sẽ thấy rõ ràng String làm kiểu tham số của phương thức được stubbed.

+0

Trước hết, cảm ơn bạn đã trả lời. Thật không may việc ghi đè phương thức không phải là một lựa chọn cho dự án. Nếu Mockito không thể làm điều đó, tôi sẽ tiếp tục giải quyết vấn đề này. – troig

+0

@troig Bạn không kiểm soát mã nguồn của các giao diện này? –

+0

Không, đó là vấn đề. Cảm ơn bạn đã tiếp cận của bạn anyway. – troig

Các vấn đề liên quan