Menyuntik Mockito Mock ke Spring Beans

1. Gambaran keseluruhan

Dalam artikel ini kami akan menunjukkan cara menggunakan suntikan ketergantungan untuk memasukkan ejekan Mockito ke Spring Beans untuk pengujian unit.

Dalam aplikasi dunia nyata, di mana komponen sering bergantung pada mengakses sistem luaran, penting untuk memberikan pengasingan ujian yang betul supaya kita dapat fokus menguji fungsi unit tertentu tanpa perlu melibatkan keseluruhan hierarki kelas untuk setiap ujian.

Menyuntik tiruan adalah cara yang bersih untuk memperkenalkan pengasingan seperti itu.

2. Pergantungan Maven

Kami memerlukan kebergantungan Maven berikut untuk ujian unit dan objek tiruan:

 org.springframework.boot spring-boot-starter 2.2.2.RELEASE   org.springframework.boot spring-boot-starter-test 2.2.2.RELEASE test   org.mockito mockito-core 2.21.0 

Kami memutuskan untuk menggunakan Spring Boot untuk contoh ini, tetapi Spring klasik juga akan berfungsi dengan baik.

3. Menulis Ujian

3.1. Logik Perniagaan

Pertama, mari buat perkhidmatan mudah yang akan kami uji:

@Service public class NameService { public String getUserName(String id) { return "Real user name"; } }

Dan masukkan ke kelas UserService :

@Service public class UserService { private NameService nameService; @Autowired public UserService(NameService nameService) { this.nameService = nameService; } public String getUserName(String id) { return nameService.getUserName(id); } }

Untuk tutorial ini, kelas yang diberikan mengembalikan satu nama tanpa mengira id yang diberikan. Ini dilakukan agar kita tidak terganggu dengan menguji logik yang rumit.

Kami juga memerlukan kelas utama Spring Boot standard untuk mengimbas kacang dan memulakan aplikasi:

@SpringBootApplication public class MocksApplication { public static void main(String[] args) { SpringApplication.run(MocksApplication.class, args); } }

3.2. Ujian

Sekarang mari beralih ke logik ujian. Pertama sekali, kita harus mengkonfigurasi konteks aplikasi untuk ujian:

@Profile("test") @Configuration public class NameServiceTestConfiguration { @Bean @Primary public NameService nameService() { return Mockito.mock(NameService.class); } }

The @Profile anotasi memberitahu Spring untuk memohon konfigurasi ini hanya apabila "ujian" profil aktif. The @Primary anotasi yang ada untuk memastikan hal ini digunakan dan bukan yang sebenar untuk autowiring. Kaedah itu sendiri membuat dan mengembalikan tiruan Mockito dari kelas NameService kami .

Sekarang kita boleh menulis ujian unit:

@ActiveProfiles("test") @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MocksApplication.class) public class UserServiceUnitTest { @Autowired private UserService userService; @Autowired private NameService nameService; @Test public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() { Mockito.when(nameService.getUserName("SomeId")).thenReturn("Mock user name"); String testName = userService.getUserName("SomeId"); Assert.assertEquals("Mock user name", testName); } }

Kami menggunakan anotasi @ActiveProfiles untuk mengaktifkan profil "ujian" dan mengaktifkan konfigurasi tiruan yang kami tulis sebelumnya. Oleh kerana itu, Spring melengkapkan contoh sebenar kelas UserService , tetapi mengejek kelas NameService . Ujian itu sendiri adalah ujian JUnit + Mockito yang agak tipikal. Kami mengkonfigurasi tingkah laku tiruan yang diinginkan, kemudian memanggil kaedah yang ingin kami uji dan menegaskan bahawa ia mengembalikan nilai yang kami harapkan.

Mungkin juga (walaupun tidak disarankan) untuk mengelakkan penggunaan profil persekitaran dalam ujian seperti itu. Untuk melakukannya, alih keluar anotasi @Profile dan @ActiveProfiles dan tambahkan anotasi @ContextConfiguration (class = NameServiceTestConfiguration.class) ke kelas UserServiceTest .

4. Kesimpulan

Dalam tutorial ringkas ini, kami menunjukkan betapa mudahnya menyuntik kodok Mockito ke Spring Beans.

Seperti biasa, semua contoh kod boleh didapati di GitHub.