Saya menggunakan Mockito untuk pengujian unit layanan nanti. Saya bingung ketika menggunakan doAnswer
vs thenReturn
.
Adakah yang bisa membantu saya secara detail? Sejauh ini saya sudah mencobanya dengan thenReturn
.
Saya menggunakan Mockito untuk pengujian unit layanan nanti. Saya bingung ketika menggunakan doAnswer
vs thenReturn
.
Adakah yang bisa membantu saya secara detail? Sejauh ini saya sudah mencobanya dengan thenReturn
.
Jawaban:
Anda harus menggunakan thenReturn
atau doReturn
jika Anda mengetahui nilai kembalian pada saat Anda memalsukan panggilan metode. Nilai yang ditentukan ini dikembalikan saat Anda menjalankan metode tiruan.
thenReturn(T value)
Menetapkan nilai kembali yang akan dikembalikan saat metode dipanggil.
@Test
public void test_return() throws Exception {
Dummy dummy = mock(Dummy.class);
int returnValue = 5;
// choose your preferred way
when(dummy.stringLength("dummy")).thenReturn(returnValue);
doReturn(returnValue).when(dummy).stringLength("dummy");
}
Answer
digunakan saat Anda perlu melakukan tindakan tambahan saat metode tiruan dipanggil, misalnya saat Anda perlu menghitung nilai hasil berdasarkan parameter panggilan metode ini.
Gunakan
doAnswer()
ketika Anda ingin menghentikan metode void dengan generikAnswer
.Jawaban menentukan tindakan yang dijalankan dan nilai yang dikembalikan saat Anda berinteraksi dengan tiruan.
@Test
public void test_answer() throws Exception {
Dummy dummy = mock(Dummy.class);
Answer<Integer> answer = new Answer<Integer>() {
public Integer answer(InvocationOnMock invocation) throws Throwable {
String string = invocation.getArgumentAt(0, String.class);
return string.length() * 2;
}
};
// choose your preferred way
when(dummy.stringLength("dummy")).thenAnswer(answer);
doAnswer(answer).when(dummy).stringLength("dummy");
}
Answer
just with return UUID.randomUUID();
.
Answer
adalah antarmuka fungsional, jadi dengan Java 8 Anda dapat menggantinya dengan ekspresi lambda. Jika tidak cukup bersih, pemfaktoran ulang biasa dan tidak biasa lainnya dimungkinkan.
doAnswer
dan thenReturn
lakukan hal yang sama jika:
Mari kita mengejek BookService ini
public interface BookService {
String getAuthor();
void queryBookTitle(BookServiceCallback callback);
}
Anda bisa menghentikan getAuthor () menggunakan doAnswer
dan thenReturn
.
BookService service = mock(BookService.class);
when(service.getAuthor()).thenReturn("Joshua");
// or..
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return "Joshua";
}
}).when(service).getAuthor();
Perhatikan bahwa saat menggunakan doAnswer
, Anda tidak dapat meneruskan metode when
.
// Will throw UnfinishedStubbingException
doAnswer(invocation -> "Joshua").when(service.getAuthor());
Jadi, ketika Anda akan menggunakan doAnswer
bukan thenReturn
? Saya dapat memikirkan dua kasus penggunaan:
Dengan menggunakan doAnswer, Anda dapat melakukan beberapa tindakan tambahan setelah pemanggilan metode. Misalnya, memicu panggilan balik di queryBookTitle.
BookServiceCallback callback = new BookServiceCallback() {
@Override
public void onSuccess(String bookTitle) {
assertEquals("Effective Java", bookTitle);
}
};
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
BookServiceCallback callback = (BookServiceCallback) invocation.getArguments()[0];
callback.onSuccess("Effective Java");
// return null because queryBookTitle is void
return null;
}
}).when(service).queryBookTitle(callback);
service.queryBookTitle(callback);
Saat menggunakan when-thenReturn on Spy Mockito akan memanggil metode nyata dan kemudian menghentikan jawaban Anda. Ini dapat menyebabkan masalah jika Anda tidak ingin memanggil metode nyata, seperti dalam contoh ini:
List list = new LinkedList();
List spy = spy(list);
// Will throw java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
when(spy.get(0)).thenReturn("java");
assertEquals("java", spy.get(0));
Dengan menggunakan doAnswer, kami dapat menghentikannya dengan aman.
List list = new LinkedList();
List spy = spy(list);
doAnswer(invocation -> "java").when(spy).get(0);
assertEquals("java", spy.get(0));
Sebenarnya, jika Anda tidak ingin melakukan tindakan tambahan setelah pemanggilan metode, Anda bisa menggunakan doReturn
.
List list = new LinkedList();
List spy = spy(list);
doReturn("java").when(spy).get(0);
assertEquals("java", spy.get(0));
doAnswer(new Answer() { ... return null;}
saya mendapatkan peringatan di gerhana untuk "Jawaban adalah tipe mentah. Referensi untuk tipe umum Jawaban <T> harus diparameterisasi". Apakah ada cara untuk menyelesaikan ini (kecuali mengabaikan peringatan c)?
code = UUID.randomUUID()
, saya menemukan tidak mungkin untuk menerapkan ini denganmockito
.