Menggunakan SpringJUnit4ClassRunner dengan Parameterized

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan melihat bagaimana untuk membuat parameter ujian integrasi Spring yang dilaksanakan di JUnit4 dengan pelari ujian JUnit Parameter .

2. SpringJUnit4ClassRunner

SpringJUnit4ClassRunner adalah pelaksanaan JUnit4 ini ClassRunner yang membenamkan Spring TestContextManager menjadi ujian JUnit .

TestContextManager adalah titik masuk ke dalam kerangka Spring TestContext dan oleh itu menguruskan akses ke Spring ApplicationContext dan suntikan kebergantungan di kelas ujian JUnit. Oleh itu, SpringJUnit4ClassRunner membolehkan pembangun melaksanakan ujian integrasi untuk komponen Spring seperti pengawal dan repositori.

Sebagai contoh, kita boleh melaksanakan ujian integrasi untuk RestController kami :

@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(classes = WebConfig.class) public class RoleControllerIntegrationTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; private static final String CONTENT_TYPE = "application/text;charset=ISO-8859-1"; @Before public void setup() throws Exception { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); } @Test public void givenEmployeeNameJohnWhenInvokeRoleThenReturnAdmin() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders .get("/role/John")) .andDo(print()) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().contentType(CONTENT_TYPE)) .andExpect(MockMvcResultMatchers.content().string("ADMIN")); } }

Seperti yang dapat dilihat dari ujian, Pengawal kami menerima nama pengguna sebagai parameter jalur dan mengembalikan peranan pengguna dengan sewajarnya.

Sekarang, untuk menguji perkhidmatan REST ini dengan kombinasi nama pengguna / peranan yang berbeza, kami harus melaksanakan ujian baru:

@Test public void givenEmployeeNameDoeWhenInvokeRoleThenReturnEmployee() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders .get("/role/Doe")) .andDo(print()) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().contentType(CONTENT_TYPE)) .andExpect(MockMvcResultMatchers.content().string("EMPLOYEE")); }

Ini dengan cepat dapat digunakan untuk mendapatkan perkhidmatan di mana sebilangan besar kombinasi input mungkin.

Untuk mengelakkan pengulangan seperti ini di kelas ujian kami, mari kita lihat bagaimana menggunakan Parameterized untuk melaksanakan ujian JUnit yang menerima pelbagai input.

3. Menggunakan Parameterized

3.1. Menentukan Parameter

Parameterized adalah pelari ujian JUnit khusus yang membolehkan kita menulis satu kes ujian dan menjalankannya terhadap beberapa parameter input:

@RunWith(Parameterized.class) @WebAppConfiguration @ContextConfiguration(classes = WebConfig.class) public class RoleControllerParameterizedIntegrationTest { @Parameter(value = 0) public String name; @Parameter(value = 1) public String role; @Parameters public static Collection data() { Collection params = new ArrayList(); params.add(new Object[]{"John", "ADMIN"}); params.add(new Object[]{"Doe", "EMPLOYEE"}); return params; } //... }

Seperti yang ditunjukkan di atas, kami menggunakan anotasi @Parameter untuk menyiapkan parameter input yang akan disuntikkan ke dalam ujian JUnit. Kami juga memberikan pemetaan nilai-nilai ini dalam nama dan peranan medan @Parameter .

Tetapi sekarang, kami mempunyai masalah lain untuk diselesaikan - JUnit tidak membenarkan beberapa pelari dalam satu kelas ujian JUnit . Ini bermakna kita tidak boleh mengambil kesempatan daripada SpringJUnit4ClassRunner menerapkan TestContextManager ke dalam kelas ujian kami. Kita mesti mencari cara lain untuk menanamkan TestContextManager .

Nasib baik, Spring memberikan beberapa pilihan untuk mencapainya. Kami akan membincangkannya dalam bahagian berikut.

3.2. Memulakan TestContextManager Secara Manual

Pilihan pertama agak mudah, kerana Spring membolehkan kita memulakan TestContextManager secara manual:

@RunWith(Parameterized.class) @WebAppConfiguration @ContextConfiguration(classes = WebConfig.class) public class RoleControllerParameterizedIntegrationTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; private TestContextManager testContextManager; @Before public void setup() throws Exception { this.testContextManager = new TestContextManager(getClass()); this.testContextManager.prepareTestInstance(this); this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); } //... }

Terutama, dalam contoh ini, kami menggunakan pelari Parameterized dan bukan SpringJUnit4ClassRunner. Seterusnya, kami menginisialisasi TestContextManager dalam kaedah setup () .

Sekarang, kita dapat melaksanakan ujian JUnit parameter:

@Test public void givenEmployeeNameWhenInvokeRoleThenReturnRole() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders .get("/role/" + name)) .andDo(print()) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().contentType(CONTENT_TYPE)) .andExpect(MockMvcResultMatchers.content().string(role)); }

JUnit akan melaksanakan kes ujian ini dua kali - sekali untuk setiap set input yang kami tetapkan menggunakan anotasi @Parameters .

3.3. SpringClassRule dan SpringMethodRule

Secara amnya, tidak digalakkan untuk memulakan TestContextManager secara manual . Sebaliknya, Spring mengesyorkan menggunakan SpringClassRule dan SpringMethodRule.

SpringClassRule mengimplementasikan JUnit's TestRule - kaedah alternatif untuk menulis kes ujian. TestRule boleh digunakan untuk menggantikan operasi penyediaan dan pembersihan yang sebelumnya dilakukan dengan kaedah @Before, @BeforeClass, @After, dan @AfterClass .

SpringClassRule membenamkan fungsi kelas peringkat TestContextManager dalam kelas ujian JUnit. Ia menginisialisasi TestContextManager dan meminta persediaan dan pembersihan Spring TestContext. Oleh itu, ia menyediakan suntikan kebergantungan dan akses ke ApplicationContext .

Selain SpringClassRule , kita juga mesti menggunakan SpringMethodRule . yang menyediakan fungsi tahap contoh dan tahap kaedah untuk TestContextManager.

SpringMethodRule bertanggungjawab untuk penyediaan kaedah ujian. Ia juga memeriksa kes ujian yang ditandai untuk dilangkau dan menghalangnya daripada berjalan.

Mari lihat bagaimana menggunakan pendekatan ini di kelas ujian kami:

@RunWith(Parameterized.class) @WebAppConfiguration @ContextConfiguration(classes = WebConfig.class) public class RoleControllerParameterizedClassRuleIntegrationTest { @ClassRule public static final SpringClassRule scr = new SpringClassRule(); @Rule public final SpringMethodRule smr = new SpringMethodRule(); @Before public void setup() throws Exception { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); } //... }

4. Kesimpulan

Dalam artikel ini, kami membincangkan dua cara untuk melaksanakan ujian integrasi Spring menggunakan pelari ujian Parameterized dan bukannya SpringJUnit4ClassRunner . Kami melihat bagaimana memulakan TestContextManager secara manual, dan kami melihat satu contoh menggunakan SpringClassRule dengan SpringMethodRule , pendekatan yang disarankan oleh Spring.

Walaupun kami hanya membincangkan Parameterized runner dalam artikel ini, kami sebenarnya boleh menggunakan salah satu pendekatan ini dengan mana-mana pelari JUnit untuk menulis ujian integrasi Spring.

Seperti biasa, semua kod contoh boleh didapati di GitHub.