Saya menggunakan Mockito @Mock
dan @InjectMocks
anotasi untuk menyuntikkan dependensi ke bidang pribadi yang dijelaskan dengan Spring @Autowired
:
@RunWith(MockitoJUnitRunner.class)
public class DemoTest {
@Mock
private SomeService service;
@InjectMocks
private Demo demo;
/* ... */
}
dan
public class Demo {
@Autowired
private SomeService service;
/* ... */
}
Sekarang saya ingin juga menyuntikkan benda nyata ke @Autowired
bidang pribadi (tanpa setter). Apakah ini mungkin atau apakah mekanisme terbatas pada menyuntikkan Mock saja?
MockitoAnnotations.initMocks(this);
dalam@Before
metodenya. Saya tahu ini tidak terkait langsung dengan pertanyaan awal, tetapi untuk siapa pun yang datang kemudian, itu perlu ditambahkan untuk membuat runnable ini.@RunWith(MockitoJUnitRunner.class)
), Anda tidak memerlukan sambunganMockitoAnnotations.initMocks(this);
Jawaban:
Gunakan
@Spy
anotasiMockito akan mempertimbangkan semua bidang yang memiliki
@Mock
atau@Spy
anotasi sebagai kandidat potensial untuk disuntikkan ke dalam instance yang dianotasi dengan@InjectMocks
anotasi. Dalam'RealServiceImpl'
contoh kasus di atas akan disuntikkan ke dalam 'demo'Untuk lebih jelasnya lihat
Rumah Mockito
@Mengintai
@Mengejek
sumber
Mockito cannot mock/spy following: - final classes - anonymous classes - primitive types
new RealServiceImpl()
,@Spy private SomeService service;
membuat objek nyata menggunakan konstruktor default sebelum memata-matai itu.Selain jawaban @Dev Blanked, jika Anda ingin menggunakan kacang yang sudah ada yang dibuat oleh Spring kode dapat dimodifikasi untuk:
Dengan cara ini Anda tidak perlu mengubah kode Anda (tambahkan konstruktor lain) hanya untuk membuat tes bekerja.
sumber
Autowired
bidang dari dependensi dibuat dengan benar.Mockito bukan kerangka kerja DI dan bahkan kerangka kerja DI mendorong suntikan konstruktor melalui suntikan lapangan.
Jadi, Anda cukup mendeklarasikan konstruktor untuk menetapkan dependensi kelas yang diuji:
Menggunakan Mockito
spy
untuk kasus umum adalah saran yang mengerikan. Itu membuat kelas tes rapuh, tidak lurus dan rentan kesalahan: Apa yang benar-benar diejek? Apa yang benar-benar diuji?@InjectMocks
dan@Spy
juga merusak keseluruhan desain karena mendorong kelas yang membengkak dan tanggung jawab campuran di kelas.Harap baca
spy()
javadoc sebelum menggunakannya secara membabi buta (penekanan bukan milikku):sumber
Di Musim Semi ada utilitas khusus yang dipanggil
ReflectionTestUtils
untuk tujuan ini. Ambil contoh spesifik dan menyuntikkan ke lapangan.sumber
Saya tahu ini adalah pertanyaan lama, tetapi kami dihadapkan dengan masalah yang sama ketika mencoba menyuntikkan Strings. Jadi kami menemukan ekstensi JUnit5 / Mockito yang sesuai dengan yang Anda inginkan: https://github.com/exabrial/mockito-object-injection
EDIT:
sumber