Merhabalar. Bu yazımızda Java projelerimizde kullandığımız Mockito kütüphanesi ile, @Transactional anotasyonuna sahip bir servise mock servis enjekte edememe probleminden ve çözümünden bahsedeceğiz.
Öncelikle, neden mock (yapay, sahte) servis kullanıldığından bahsedelim. Unit test yazarken testin gerçekten unit olması için test ettiğiniz kod parçasının başka kodlara bağımlılığının olmaması gerekmektedir. Örneğin, sipariş toplam ücretini hesaplayan bir servis düşünelim. Ham ücrete eklenen vergi miktarını başka bir servisten hesaplatıp kullandığını düşünelim. Sipariş ücretini hesaplayan metodu sağlıklı test edebilmek için, vergiyi hesaplayan metoddan hatalı sonuç dönmeyeceğinden emin olmalıyız. Bu nedenle vergi hesaplayan metodun orjinal kodunu çalıştırmadan, doğrudan istediğimiz sonucu dönmesi için vergi servisini "mocklarız".
Mockito çatısını kullanırken bu işlemi @Mock anotasyonu ile yaparız. Test ettiğimiz servisin içindeki bir servise mock sevisimizi enjekte etmek için @InjectMocks anotasyonunu kullanırız. Yalnız, inject edilen servis @Transactional anotasyonuna sahip ise, enjekte işlemi gerçekleşmiyor. Çünkü, transactional servis, java proxy nesneye dönüştürüldüğü için, Mockito enjekte edecek sınıf elemanı bulamıyor. Bu problemi aşmak için, mock servisleri hazırladığımız sırada, ReflectionTestUtils kullanarak manuel olarak servisi enjekte ederek aşabiliriz.
Aşağıdaki kodlarla daha anlaşılır olacaktır.
"admin" kullanıcı adını dönen UserService.
UserService'den dönen kullanıcı adını customerName olarak dönen CustomerService.
UserService sınıfının getUserName metodunu mock user name dönmesini istememize rağmen, CustomerService @Transactional olduğundan içindeki UserService mocklanamadığı için test başarısız olmaktadır.
CustomerService içindeki UserService ReflectionTestUtils ile mocklandığı için, test başarılı sonuçlanmaktadır.
0 Yorumlar