Saya baru mengenal Spring Boot dan mencoba memahami cara kerja pengujian di SpringBoot. Saya agak bingung tentang apa perbedaan antara dua cuplikan kode berikut:
Cuplikan kode 1:
@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerApplicationTest {
@Autowired
private MockMvc mvc;
@Test
public void getHello() throws Exception {
mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(equalTo("Greetings from Spring Boot!")));
}
}
Tes ini menggunakan @WebMvcTest
anotasi yang saya yakini untuk pengujian potongan fitur dan hanya menguji lapisan MVC dari aplikasi web.
Cuplikan kode 2:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void getHello() throws Exception {
mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(equalTo("Greetings from Spring Boot!")));
}
}
Tes ini menggunakan @SpringBootTest
anotasi dan a MockMvc
. Jadi, apa bedanya dengan cuplikan kode 1? Apa yang dilakukannya secara berbeda?
Edit: Menambahkan Cuplikan Kode 3 (Temukan ini sebagai contoh pengujian integrasi dalam dokumentasi Spring)
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerIT {
@LocalServerPort private int port;
private URL base;
@Autowired private TestRestTemplate template;
@Before public void setUp() throws Exception {
this.base = new URL("http://localhost:" + port + "/");
}
@Test public void getHello() throws Exception {
ResponseEntity < String > response = template.getForEntity(base.toString(), String.class);
assertThat(response.getBody(), equalTo("Greetings from Spring Boot!"));
}
}
sumber
SpringBootTest
sedang memuat aplikasi lengkap Anda (untuk beberapa perluasan, secara default ini tidak akan memulai penampung tersemat jika ada yang tersedia, untuk itulahwebEnvironment
ada). Saya tidak akan mengatakan itu@SpringBootTest
adalah tes unit pengontrol tetapi lebih merupakan tes integrasi, sungguh.WebMvcTest
benar-benar merupakan pengujian unit pengontrol Anda dalam arti bahwa jika memiliki ketergantungan, Anda harus menyediakannya sendiri (baik konfigurasi atau semacam tiruan).SpringBootTest
danWebMvcTest
buat sangat berbeda. Yang pertama memuat aplikasi SELURUH Anda dan mengaktifkan SEMUA konfigurasi otomatis sedangkan yang terakhir hanya mengaktifkan Spring Mvc dan tidak memindai apa pun kecualiHelloController
. Itu semua tergantung apa yang Anda maksud dengan tes unit. Tapi itulah perbedaannya.Anotasi @SpringBootTest memberi tahu Spring Boot untuk pergi dan mencari kelas konfigurasi utama (misalnya dengan @SpringBootApplication), dan menggunakannya untuk memulai konteks aplikasi Spring. SpringBootTest memuat aplikasi lengkap dan menyuntikkan semua kacang yang bisa jadi lambat.
@WebMvcTest - untuk menguji lapisan pengontrol dan Anda perlu menyediakan dependensi yang tersisa yang diperlukan menggunakan Objek Mock.
Beberapa penjelasan di bawah ini untuk referensi Anda.
Menguji irisan aplikasi Kadang-kadang Anda ingin menguji “irisan” sederhana dari aplikasi daripada mengonfigurasi keseluruhan aplikasi secara otomatis. Spring Boot 1.4 memperkenalkan 4 anotasi pengujian baru:
Lihat informasi lebih lanjut: https://spring.io/guides/gs/testing-web/
sumber
Pengujian MVC dimaksudkan untuk mencakup bagian pengontrol aplikasi Anda saja. Permintaan dan tanggapan HTTP diolok-olok sehingga koneksi yang sebenarnya tidak dibuat. Di sisi lain, saat Anda menggunakan
@SpringBootTest
, semua konfigurasi untuk konteks aplikasi web dimuat dan koneksi akan melalui server web yang sebenarnya. Dalam hal ini, Anda tidak menggunakanMockMvc
kacang melainkan standarRestTemplate
(atau alternatif baruTestRestTemplate
).Jadi, kapan kita harus memilih salah satu?
@WebMvcTest
dimaksudkan untuk menguji pengontrol secara terpadu dari sisi server.@SpringBootTest
, di sisi lain, harus digunakan untuk pengujian integrasi, ketika Anda ingin berinteraksi dengan aplikasi dari sisi klien.Itu tidak berarti bahwa Anda tidak dapat menggunakan ejekan dengan
@SpringBootTest
; jika Anda sedang menulis pengujian integrasi, itu mungkin masih diperlukan. Bagaimanapun, lebih baik tidak menggunakannya hanya untuk pengujian unit pengontrol sederhana.sumber - Mempelajari Layanan Mikro dengan Spring Boot
sumber
@SpringBootTest
, server web yang sebenarnya tidak dijalankan kecuali Anda juga memilikiwebEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
(atau aDEFINED_PORT
) dan koneksi tidak melalui server web yang sebenarnya. Default untuk@SpringBootTest
adalahWebEnvironment.MOCK
.