Contract Based Testing Nedir?

Metin Alnıaçık
2 min readJan 31, 2022

--

Unit testlerle uygulamanız içerisindeki her türlü iş mantığı (business logic) değişikliği yakayabilirsiniz. Eğer bir microservice mimariye sahip bir uygulamanız varsa ve provider olan serviste bir değişiklik yapıldığında, consumer olan servis veya servislerin haberinin olmasını istiyorsanız bu durumda contact based test yazmalısınız. Bir örnek ile konuyu pekiştirelim.

İlk olarak provider servisini oluşturalım.

pom.xml dosyasına aşağıdakiler eklenir.

  • spring-cloud-starter-contract-verifier bağımlılığını ekliyoruz.
  • spring-cloud-dependencies için dependency management ekliyoruz.
  • Son olarak bir plugin ekliyoruz.

Bu kısımda dikkat etmemiz gereken nokta, baseClassForTests tag’ında verilmiş olan sınıftır. Bu sınıf daha sonra oluşturacağımız contract dosyası sınıfını referans alacaktır.

baseClassForTests tag’ındaki bahsi geçen sınıfı oluşturalım. İlgili sınıf test paketinin altındaki java klasörünün altında oluşturulur.

Provider servisinde son olarak contract dosyasını oluşturuyoruz. Test paketinin altında resources onun altına da contracts klasörü oluşturulur.

Groovy uzantılı contract dosyasını oluşturalım.
contract_for_get_course_id.groovy

Bu dosyadaki /courses/1 URL’ine GET isteği atıldığında response olarak body kısmındaki bilgi dönecektir.

Örneğin tamamen anlaşılabilmesi için diğer sınıfları da ekleyelim.

Model (Course.java)

Service (CourseService.java)

Controller (CourseController.java)

Provider servisimizi maven, clean, test yaparak testini gerçekleştirelim.

Bir tane test çalıştı ve başarılı bilgisi görüntülendi.

Şimdi örnek üzerinde ufak bir değişiklik yapalım. Course modelinin içindeki id bilgisini courseId olarak güncelleyelim.

Tekrer maven, clean, test yaptığımızda hata ile karşılaşırız. Hata açıklaması aşağıdaki gibidir.

java.lang.IllegalStateException: Parsed JSON [{“courseId”:1,”name”:”Java”,”must”:true}] doesn’t match the JSON path [$[?(@.[‘id’] == 1)]]

courseId alanı contract’taki JSON da id olarak tanımlanmış yani contract sağlanmamıştır. Yapmış olduğumuz test servisin kendi içinde gerçekleştirildi.

Şimdi consumer servisi oluşturalım.

Consumer servisinin pom.xml dosyasına aşağıdakiler eklenmelidir.

  • Provider servisi stub olarak kullanmak için aşağıdaki bağımlılık eklenir.
  • spring-cloud-dependencies için dependency management ekliyoruz.
  • Son olarak bir plugin ekliyoruz.

Atacağımız sorgu sonucu Course modeli olacağından provider servisteki Course.java dosyasını consumer servisine kopyalıyoruz.

Test klasörünün altına resources onun altına da contracts klasörü eklenir.

Test sınıfını ekleyelim. ConsumerApplicationTests.java

12. satır sayesinde, TestRestTemplate sınıfını inject ederek kullanabilirsiniz.

15. satırda, hangi provider servisini stub olarak kullanmak istiyorsanız, o servisin groupId, artifactId ve çalışmasını istediğiniz port bilgisini giriniz.

Consumer servisi maven, clean, test çalıştırıldığında sorunsuz çalışacaktır.

Son olarak, servisler arası contract sağlanmadığındaki durumu test edelim. Consumer servisteki Course sınıfının id alanını courseId olarak değiştirip maven, clean, test yaptığınızda, courseId değeri null geldiği için hata oluşacaktır.

Örneğin tamamına github adresimden ulaşabilirsiniz.

İyi günler,
Bol kodlamalar :)

--

--