Saat membuat tes dan mengejek dependensi, apa perbedaan antara ketiga pendekatan ini?
@MockBean:
@MockBean MyService myservice;
@Mengejek:
@Mock MyService myservice;
Mockito.mock ()
MyService myservice = Mockito.mock(MyService.class);
Perpustakaan Mockito polos
import org.mockito.Mock;
...
@Mock
MyService myservice;
dan
import org.mockito.Mockito;
...
MyService myservice = Mockito.mock(MyService.class);
berasal dari perpustakaan Mockito dan secara fungsional setara.
Mereka memungkinkan untuk mengejek kelas atau antarmuka dan untuk merekam dan memverifikasi perilaku di dalamnya.
Cara menggunakan anotasi lebih pendek, jadi lebih disukai dan sering disukai.
Perhatikan bahwa untuk mengaktifkan anotasi Mockito selama pelaksanaan pengujian,
MockitoAnnotations.initMocks(this)
metode statis harus dipanggil.
Untuk menghindari efek samping antara tes, disarankan untuk melakukannya sebelum setiap pelaksanaan tes:
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
Cara lain untuk mengaktifkan anotasi Mockito adalah memberi anotasi pada kelas uji dengan @RunWith
menetapkan MockitoJUnitRunner
yang mengerjakan tugas ini dan juga hal-hal berguna lainnya:
@RunWith(org.mockito.runners.MockitoJUnitRunner.class)
public MyClassTest{...}
Perpustakaan Spring Boot yang membungkus perpustakaan Mockito
Ini memang kelas Spring Boot :
import org.springframework.boot.test.mock.mockito.MockBean;
...
@MockBean
MyService myservice;
Kelas termasuk dalam spring-boot-test
perpustakaan.
Memungkinkan untuk menambahkan mockito mock di Spring ApplicationContext
.
Jika kacang, yang kompatibel dengan kelas yang dideklarasikan ada dalam konteks, itu menggantikannya dengan tiruan.
Jika bukan itu masalahnya, ia menambahkan tiruan dalam konteks sebagai kacang.
Referensi Javadoc:
Anotasi yang dapat digunakan untuk menambahkan tiruan ke Spring ApplicationContext.
...
Jika ada satu kacang tunggal dengan tipe yang sama yang didefinisikan dalam konteks akan digantikan oleh mock, jika tidak ada kacang yang ada didefinisikan yang baru akan ditambahkan.
Kapan menggunakan Mockito klasik / polos dan kapan digunakan @MockBean
dari Spring Boot?
Tes unit dirancang untuk menguji komponen yang terpisah dari komponen lain dan pengujian unit juga memiliki persyaratan: menjadi secepat mungkin dalam hal waktu eksekusi karena pengujian ini dapat dilakukan setiap hari selusin kali pada mesin pengembang.
Konsekuensinya, berikut adalah pedoman sederhana:
Saat Anda menulis tes yang tidak memerlukan dependensi dari wadah Spring Boot, Mockito klasik / polos adalah cara untuk mengikuti: cepat dan mendukung isolasi komponen yang diuji.
Jika pengujian Anda harus bergantung pada wadah Boot Musim Semi dan Anda juga ingin menambahkan atau mengejek salah satu wadah kacang: @MockBean
dari Boot Musim Semi adalah caranya.
Penggunaan khas Boot Musim Semi @MockBean
Saat kami menulis kelas uji yang dijelaskan dengan @WebMvcTest
(uji web slice).
Dokumentasi Spring Boot merangkum dengan sangat baik:
Seringkali
@WebMvcTest
akan terbatas pada pengontrol tunggal dan digunakan bersama dengan@MockBean
untuk menyediakan implementasi tiruan untuk kolaborator yang diperlukan.
Berikut ini sebuah contoh:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest(FooController.class)
public class FooControllerTest {
@Autowired
private MockMvc mvc;
@MockBean
private FooService fooServiceMock;
@Test
public void testExample() throws Exception {
Foo mockedFoo = new Foo("one", "two");
Mockito.when(fooServiceMock.get(1))
.thenReturn(mockedFoo);
mvc.perform(get("foos/1")
.accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(content().string("one two"));
}
}
@MockBean
akan menggantikan kacang dalam konteks aplikasi jika kacang menyatakan jenis yang sama sudah didefinisikan dalam konfigurasi Spring Anda. Dan injeksi dilakukan di kelas di mana Anda mendeklarasikan@MockBean.
mekanisme DI bekerja dengan cara ini: Anda mendaftarkan objek dalam konteks DI dan kemudian Anda bisa menyuntikkan objek yang dirujuk dalam konteks Spring di kelas tertentu. Anda tidak menyuntikkan objek dalam konteks DI.Pada akhirnya mudah dijelaskan. Jika Anda hanya melihat javadocs dari anotasi Anda akan melihat perbedaannya:
@Mock: (
org.mockito.Mock
)@MockBean: (
org.springframework.boot.test.mock.mockito.MockBean
)Mockito.mock ()
sumber
@MockBean
dan@Mock
yang satu akan menyuntikkan mock ke dalamSpring ApplicationContext
dan yang lain tidak?