gọi lại mockito và nhận giá trị đối số


88

Tôi không gặp may khi Mockito nắm bắt các giá trị đối số của hàm! Tôi đang chế nhạo một chỉ mục của công cụ tìm kiếm và thay vì xây dựng một chỉ mục, tôi chỉ đang sử dụng một hàm băm.

// Fake index for solr
Hashmap<Integer,Document> fakeIndex;

// Add a document 666 to the fakeIndex
SolrIndexReader reader = Mockito.mock(SolrIndexReader.class);

// Give the reader access to the fake index
Mockito.when(reader.document(666)).thenReturn(document(fakeIndex(666))

Tôi không thể sử dụng các đối số tùy ý vì tôi đang kiểm tra kết quả của các truy vấn (tức là tài liệu nào chúng trả về). Tương tự như vậy, tôi không muốn chỉ định một giá trị cụ thể cho và có một dòng cho mỗi tài liệu!

Mockito.when(reader.document(0)).thenReturn(document(fakeIndex(0))
Mockito.when(reader.document(1)).thenReturn(document(fakeIndex(1))
....
Mockito.when(reader.document(n)).thenReturn(document(fakeIndex(n))

Tôi đã xem phần gọi lại trên trang Sử dụng Mockito . Thật không may, nó không phải là Java và tôi không thể hiểu được điều đó để hoạt động trong Java.

CHỈNH SỬA (để làm rõ): Làm cách nào để Mockito nắm bắt đối số X và chuyển đối số đó vào hàm của tôi? Tôi muốn giá trị chính xác (hoặc ref) của X được truyền vào hàm.

Tôi không muốn liệt kê tất cả các trường hợp và đối số tùy ý sẽ không hoạt động vì tôi đang thử nghiệm các kết quả khác nhau cho các truy vấn khác nhau.

Trang Mockito nói

val mockedList = mock[List[String]]
mockedList.get(anyInt) answers { i => "The parameter is " + i.toString } 

Đó không phải là java và tôi không biết cách dịch sang java hoặc chuyển bất cứ điều gì đã xảy ra vào một hàm.


Tôi không chắc mình hiểu chính xác điều gì đang khiến bạn thất bại. Cuộc gọi của bạn đến Mockito.when(reader.document(666)).thenReturn(document(fakeIndex(666))sẽ thiết lập đối tượng giả cho bạn. Điều gì xảy ra khi bạn gọi reader.document(666)?
caffein vào

666 hoạt động tốt. Tuy nhiên, tôi muốn có thể chuyển một số cụ thể X và nhận được kết quả là fakeIndex (X). Tôi có một số lượng lớn tài liệu tiềm năng để kiểm tra các truy vấn và tôi không muốn nhập tất cả.
nflacco

Câu trả lời:


103

Tôi chưa bao giờ sử dụng Mockito, nhưng muốn tìm hiểu, vì vậy hãy bắt đầu. Nếu ai đó ít hiểu hơn tôi trả lời, hãy thử câu trả lời của họ trước!

Mockito.when(reader.document(anyInt())).thenAnswer(new Answer() {
 public Object answer(InvocationOnMock invocation) {
     Object[] args = invocation.getArguments();
     Object mock = invocation.getMock();
     return document(fakeIndex((int)(Integer)args[0]));
     }
 });

2
Tôi chỉ nhận thấy liên kết ở phía bên phải tới Mockito: Cách thực hiện một phương thức trả về một đối số đã được chuyển cho nó . Có vẻ như tôi đang ở gần, nếu không phải là phát hiện ra.
Ed Staub

uy tín của người dùng mạnh mẽ (666) so với tương quan câu hỏi ban đầu! Điều đó hoạt động rất tốt. Chỉ thay đổi tôi thực hiện để có được công cụ biên dịch được đặt nào trước câu trả lời Object (InvocationOnMock gọi) ....
nflacco

54

Kiểm tra ArgumentCaptors:

https://site.mockito.org/javadoc/current/org/mockito/ArgumentCaptor.html

ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
Mockito.when(reader.document(argument.capture())).thenAnswer(
  new Answer() {
    Object answer(InvocationOnMock invocation) {
      return document(argument.getValue());
    }
  });

3
Wow, tôi không biết bạn có thể sử dụng ArgumentCaptors để khai thác. Có một cảnh báo lớn về nó trong liên kết đó. Tiến hành thận trọng.
einnocent

3
Đúng, bạn nói đúng. Tụ điện chỉ nên được sử dụng với xác minh.
Qualidafial

41

Bạn có thể muốn sử dụng verify () kết hợp với ArgumentCaptor để đảm bảo thực thi trong thử nghiệm và ArgumentCaptor để đánh giá các đối số:

ArgumentCaptor<Document> argument = ArgumentCaptor.forClass(Document.class);
verify(reader).document(argument.capture());
assertEquals(*expected value here*, argument.getValue());

Giá trị của đối số rõ ràng là có thể truy cập thông qua đối số.getValue () để thao tác / kiểm tra thêm hoặc bất cứ điều gì bạn muốn làm.


2
Câu trả lời tốt nhất: thẳng về phía trước, dễ hiểu
Radu Cugut

Không trả lời câu hỏi. Câu hỏi là về Mockito.when và không xác minh.
seBaka28

@ seBaka28 giải pháp tốt nhất để nhận đối số là trình bắt giữ đối số. ArgumentCaptors được các tác giả của Mockito khuyên nên sử dụng cùng với xác minh, vì vậy tôi muốn đưa ra câu trả lời toàn cảnh. nếu bạn chọn không sử dụng chúng, đó là lựa chọn của bạn, nhưng không được khuyên. CHỈNH SỬA: Tôi không thấy điều này biện minh cho việc phản đối như thế nào, nhưng đó cũng là lựa chọn của bạn.
fl0w

1
Bởi vì nó không trả lời câu hỏi. Có, ArgumentCaptor là tuyệt vời khi bạn muốn nắm bắt đối số, nhưng bạn không thể sử dụng nó kết hợp với when (...). ThenReturn () là những gì OP đang cố gắng thực hiện: Dựa trên một tham số nhất định, một dịch vụ giả mạo nghĩa là trả về một đối tượng cụ thể.
seBaka28

1
@YuraHoy đó là thông báo lỗi tiêu chuẩn khi bạn sử dụng xác minh và đối tượng hoặc phương thức được gọi thường xuyên hơn bạn đã yêu cầu xác minh. Bạn có thể thay đổi số lượng kỳ vọng bằng cách thêm đối số times (n) như sau: xác minh (người đọc, lần (5)) - điều này sẽ mong đợi 5 tương tác. Để tham khảo xin vui lòng xem: baeldung.com/mockito-verify
fl0w

13

Với Java 8, đây có thể là một cái gì đó như thế này:

Mockito.when(reader.document(anyInt())).thenAnswer(
  (InvocationOnMock invocation) -> document(invocation.getArguments()[0]));

Tôi giả định đó documentlà một bản đồ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.