Selamlar, bugün size mocklama mantığı ve Wiremock kullanımı hakkında bilgi vermeye çalışacağım.
Mock(sahte) nesneler gerçek nesnelerin davranışını kontrollü olarak taklit eden benzetilmiş nesnelerdir. Bir nesnenin davranışını test etmek için o nesnenin bağımlılıklarının mocklanmasına ihtiyacımız vardır. Ayrıca bir apiyi test ederken bağımlı olduğu bileşenleri mocklayarak diğer apilerdeki hatalı durumların bizim apimizin stabilitesini bozmasının da önüne geçebiliriz.
Öncelikle bir apiye istek atıp işlem yapan basit bir api yazacağım ardından bu isteği wiremock ile nasıl mocklayacağımıza değineceğim. İstek atacağım api olarak The Star Wars Api’yi seçtim. https://swapi.dev/documentation adresinden kullanımı hakkında bilgi sahibi olabilirsiniz.
Makalemde kullanmış olduğum 2 projeyi aşağıdan inceleyebilirsiniz.
Apimizi java dilinde yazdım ve spring boot kullandım. Apinin tek bir endpoint’i var ve bu post /createOrder işlemini yapan endpointimde kullanıcıdan istenilen orderRequest aşağıdaki gibidir.
Burdaki peopleId alanındaki değeri alarak swapi’ye call atıyorum. Örneğin peopleId 1 girildiğinde https://swapi.dev/api/people/1 adresine gidip aşağıdaki response’u dönüyor.
Daha sonrasında response olarak yukarıdaki swapinin döndüğü PeopleResponse objesini ve girilen peopleId, orderName ve orderDescription değerlerini döneceğim. Bu çok basit bir api olduğu için db kullanmaya ihtiyaç duymadım. Aşağıda örnek bir orderResponse bulunmaktadır.
Ayrıca apime eğer gelen PeopleResponse objesindeki name değeri Darth Vader ise “Darth Vader cannot create an order.” şeklinde 400 dönen bir hata mesajı da ekledim. Örnek Response aşağıda görünmektedir.
Benim bu apiyi izole bir ortamda kaldırdığımı varsayalım. Ben /createOrder işlemini yaptığımda swapi’ye istek atacak fakat swapi bu izole ortamda bulunmadığı için hata alacak dolayısıyla ben apimin doğru şekilde çalışıp çalışmadığını kontrol edemeyeceğim. Doğru bir şekilde çalışıp çalışmadığını kontrol edebilmem için benim swapi’yi mocklamam gerekmektedir. Burada imdadımıza wiremock yetişmektedir.
Wiremock web servislerini mocklamak için kullanılabilecek bir kütüphanedir. Kullanımı oldukça basittir. Localde aşağıdaki komutla docker üzerinden kaldırdığım http://localhost:8083/ adresine bakmaktadır.
> docker run -it — rm -p 8083:8083 wiremock/wiremock — port 8083
basic-order-api projesinde SwapiServiceClient class’ındaki retrofit’e baseUrl’in http://localhost:8083/ olduğunu yazıyorum ve apiyi ayağa kaldırıyorum. Wiremock sayesinde /people/{customer_id} endpoint’ine call atmasını simüle edebileceğim.
Bunun için öncelikle basic-order-api-acceptance-test projesini oluşturuyorum. Apimizde kullandığım modelleri bu projeye ekliyorum. Burda RestAssured kullanarak apimize call atıyorum. Ardından testlerimi yazmaya başlıyorum. shouldCreateOrder ve shouldNotCreateOrderWhenPeopleIsDarthVader şeklinde 2 testim var. Burda apinin düzgün çalışması için örneğin OrderRequest’imde peopleId 1 gönderdiğimde wiremockta http://localhost:8083/people/1 adresinde bir People response objesi oluşturmam gerekiyor. Bunu da aşağıda yazdığım method ile sağlıyorum. StubFor methodu ile bir mock oluşturacağımı belirtiyorum. Get methodu içine döneceğim endpoint’i veriyorum ve willReturn methodu içinde de withStatus dönmek istediğim http status kod değeri, withHeader döneceğim Header değeri ve withBody döneceğim Body değeri bulunmakta.
Burda mockla kapsamak istediğim özel durumlar olursa onu da handle edebilirim. Hatırlasanız ben apimizde eğer people name’i DarthVader ise “Darth Vader cannot create an order.” şeklinde mesaj atan ve 400 dönen bir kontrol yazmıştım. Bunun testini yapmak için methoda bir boolean isDarthVader kontrolü ekledim eğer bu değer true ise PeopleResponse’daki name değerine Darth Vader setleniyor böylece bende bu durumu handle edebiliyorum.
shouldCreateOrder testimizde mock’a isDarthVader flag’ini false gönderiyorum böylece elimde yazdığım randomDataProviderdan dolayı name değeri Luke Skywalker olan bir PeopleResponse dönüyor ve ben de apimize call attığımda peopleResponse’un 200 döndüğünü ve diğer assertionlarımın geçtiğini görüyorum.
shouldNotCreateOrderWhenPeopleIsDarthVader testimizde ise yukarıda bahsettiğim isDarthVader flagini true dönüyorum ve böylece apimizden 400 döndüğünü ve ErrorResponse’un message değerinin “Darth Vader cannot create order” olduğunu assert ediyorum.
localhosttaki wiremock’un döndüğü response objesini görmek istersem http://localhost:8083/people/{peopleId} değerini tarayıcıma girerek oluşan objeyi görebilirim.
Oluşan tüm mockları görmek için http://localhost:8083/__admin/mappings adresine girerim.
Wiremock hakkında daha detaylı bilgi için https://wiremock.org/docs adresine göz atabilirsiniz.
Mocklamanın yaratacağı sıkıntılara örnek olarak mockladığımız objelerin kontratınının değişmesini verebiliriz. Bu durumda bizim mockumuza göre izole ortamda api çalışmaya devam edecek fakat gerçek bağımlılığın bulunduğu ortamda hata alacaktır. Bu durumun önüne geçebilmek için kontrat testi yazmalıdır. Kontrat testi hata aldığında ilgili apinin modellerinde bir değişiklik olduğunu farkederiz.
Basit bir şekilde mocklama mantığı ve Wiremock kullanımı hakkında bilgi vermeye çalıştım umarım faydalı olmuştur. Bir sonraki yazımda görüşmek üzere kendinize iyi bakın.