Birim testi, yazılım geliştirmede kodunuzun güvenilirliğini ve doğruluğunu sağlayan temel bir uygulamadır. Bu makalede, basit kod örnekleri, parametrelendirme, istisna testi, @Before
, @BeforeEach
, @After
ve @AfterEach
gibi ek açıklamaların yanı sıra örnek ve taslakların kullanımı da dahil olmak üzere Java birim testinin temel kavramlarını inceleyeceğiz. .
Ayrıca alay etmek için popüler Mockito kitaplığını tanıtacağız ve Maven eklentilerini kullanarak kod kapsamının ölçülmesi konusunda rehberlik sağlayacağız.
Birim testi, doğruluğunu doğrulamak için ayrı ayrı bileşenlerin veya kod birimlerinin ayrı ayrı test edilmesi uygulamasıdır. Birincil amaç, geliştirme sürecinin başlarında hataları tespit edip düzeltmek, böylece her kod biriminin beklendiği gibi davranmasını sağlamaktır.
Örneklerimiz için kullanabileceğimiz basit bir hesap makinesi sınıfı oluşturarak başlayalım. Calculator
sınıfı temel aritmetik işlemleri içerir:
public class Calculator { public int add(int a, int b) { return a + b; } public int subtract(int a, int b) { return a - b; } public int multiply(int a, int b) { return a * b; } public int divide(int a, int b) { return a / b; } }
Calculator
sınıfımıza yönelik bir birim testi oluşturmak için Java için popüler bir test çerçevesi olan JUnit çerçevesini kullanabilirsiniz. add
yöntemi için basit bir birim testi yazalım:
import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class CalculatorTest { @Test public void testAdd() { Calculator calculator = new Calculator(); int result = calculator.add(2, 3); assertEquals(5, result); } }
Bu testte gerekli JUnit sınıflarını içe aktarıyoruz ve test yöntemine @Test
ile açıklama ekliyoruz. Daha sonra Calculator
sınıfının bir örneğini oluşturuyoruz ve add
yönteminin sonucunun beklenen değere (5) eşit olduğunu iddia ediyoruz.
Parametrelendirilmiş testler, aynı test mantığını birden fazla giriş verisi kümesiyle çalıştırmanıza olanak tanır. Bu, çeşitli giriş değerlerine sahip bir yöntemi test etmek için kullanışlıdır. Bunu JUnit'te yapmak için @ParameterizedTest
ek açıklamasını kullanabilir ve giriş değerlerini ve beklenen sonuçları parametre olarak sağlayabilirsiniz. İşte bir örnek:
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import static org.junit.jupiter.api.Assertions.assertEquals; public class CalculatorTest { @ParameterizedTest @CsvSource({"2, 3, 5", "4, 7, 11", "0, 0, 0"}) public void testAdd(int a, int b, int expected) { Calculator calculator = new Calculator(); int result = calculator.add(a, b); assertEquals(expected, result); } }
Bu örnekte @ParameterizedTest
ek açıklaması, birden fazla giriş değeri kümesi ve beklenen sonuçları CSV formatında sunmamıza olanak tanır. add
yönteminin doğruluğu sağlanarak her kombinasyon için test yöntemi yürütülür.
İstisnaları test etmek, kodunuzun hataları uygun şekilde işlemesini sağlamak için çok önemlidir. İstisna durumlarını test etmek için JUnit tarafından assertThrows
yöntemiyle birlikte @Test
ek açıklamasını kullanabilirsiniz.
İşte bir örnek:
javaCopy codeimport org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertThrows; public class CalculatorTest { @Test public void testDivideByZero() { Calculator calculator = new Calculator(); assertThrows(ArithmeticException.class, () -> calculator.divide(5, 0)); } }
Bu testte, Calculator
sınıfında bir sayının sıfıra bölünmesinin bir ArithmeticException
oluşturduğunu doğrularız.
@Before
, @BeforeEach
, @After
ve @AfterEach
gibi ek açıklamalar test ortamını kurmak ve yıkmak için kullanılır. Bu ek açıklamalar, ortak test başlatma ve temizleme görevlerinin yönetilmesine yardımcı olur.
@Before
ve @After
test sınıfındaki tüm test yöntemlerinden önce ve sonra sırasıyla bir kez çalıştırılır.@BeforeEach
ve @AfterEach
her test yönteminden önce ve sonra çalışır.
İşte bir örnek:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class CalculatorTest { private Calculator calculator; @BeforeEach public void setUp() { calculator = new Calculator(); } @AfterEach public void tearDown() { calculator = null; } @Test public void testAdd() { int result = calculator.add(2, 3); assertEquals(5, result); } @Test public void testSubtract() { int result = calculator.subtract(5, 3); assertEquals(2, result); } }
Bu örnekte, setUp
yöntemine @BeforeEach
ile açıklama eklenmiştir ve her testten önce Calculator
nesnesini başlatır. @AfterEach
ile açıklamalı tearDown
yöntemi, her testten sonra kaynakları temizler.
Test edilen kodu veritabanları veya web hizmetleri gibi harici bağımlılıklardan izole etmek istediğinizde birim testinde taklitler ve taslaklar çok önemlidir. Bu bağımlılıkların davranışını simüle etmenize olanak tanırlar.
Calculator
sınıfını, dış bağımlılık içeren bir yöntem içerecek şekilde genişletelim ve ardından bu bağımlılığı simüle etmek için bir saplama oluşturalım.
public class Calculator { private ExternalService externalService; public Calculator(ExternalService externalService) { this.externalService = externalService; } public int performComplexCalculation(int a, int b) { int result = externalService.multiply(a, b); return result + externalService.getConstant(); } }
Bu güncellenmiş Calculator
sınıfında, performComplexCalculation
çarpma ve sabit bir değer elde etme için bir ExternalService
dayanır.
Gerçek ExternalService
bağlı olmadan Calculator
sınıfını test etmek için nasıl bir saplama oluşturabileceğiniz aşağıda açıklanmıştır.
import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; public class CalculatorTest { @Test public void testPerformComplexCalculation() { // Create a stub for ExternalService ExternalService externalServiceStub = new ExternalService() { @Override public int multiply(int a, int b) { return a * b; } @Override public int getConstant() { return 5; // Stubbed constant value } }; // Create the Calculator with the stubbed ExternalService Calculator calculator = new Calculator(externalServiceStub); // Test the performComplexCalculation method int result = calculator.performComplexCalculation(2, 3); assertEquals(11, result); // 2*3 + 5 (constant) = 11 } }
Bu testte, gerekli yöntemleri geçersiz kılan anonim bir sınıf oluşturularak, ExternalService
test yönteminin içine yerleştirilir. Bu şekilde Calculator
test yöntemi, ExternalService
gerçek uygulamasına bağlı olmadan çalışır.
Saplamalar, bir sınıfın veya yöntemin belirli işlevselliğini izole etmek ve test etmek amacıyla harici sistemlerin veya bağımlılıkların davranışını simüle etmek için kullanışlıdır. Bu, saplamanın davranışını kontrol etmenize ve gerçek harici hizmetlere ihtiyaç duymadan test edilen üniteye odaklanmanıza olanak tanır.
Mockito, sahte nesneler oluşturmak ve yönetmek için kullanılan popüler bir Java kütüphanesidir. Diyelim ki harici bir ödeme ağ geçidiyle etkileşime giren bir PaymentService
sınıfımız var. Ödeme ağ geçidi için bir örnek oluşturmak amacıyla Mockito'yu kullanabiliriz:
import org.junit.jupiter.api.Test; import static org.mockito.Mockito.*; public class PaymentServiceTest { @Test public void testProcessPayment() { PaymentGateway paymentGateway = mock(PaymentGateway.class); PaymentService paymentService = new PaymentService(paymentGateway); when(paymentGateway.charge(100.0)).thenReturn(true); boolean result = paymentService.processPayment(100.0); assertTrue(result); verify(paymentGateway, times(1)).charge(100.0); } }
Bu örnekte, sahte bir PaymentGateway
oluşturuyoruz ve davranışını tanımlamak için when
yöntemini kullanıyoruz. Daha sonra PaymentService
sınıfında processPayment
yöntemini çağırırız ve charge
yönteminin beklenen parametrelerle çağrıldığını doğrularız.
Kod kapsamı, birim testleriniz tarafından yürütülen kod satırlarının, dalların veya ifadelerin yüzdesini ölçer. Test edilmemiş kodu ve ek test gerektirebilecek alanları belirlemenize yardımcı olur.
Maven, Java projeleri için popüler bir oluşturma aracıdır ve JaCoCo gibi eklentileri kullanarak kod kapsamı analizini Maven projenize entegre edebilirsiniz. JaCoCo'yu projenize nasıl ekleyeceğiniz aşağıda açıklanmıştır:
pom.xml
dosyasını açın. <build> <plugins> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.7</version> <executions> <execution> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Maven yapınızı aşağıdaki komutla çalıştırın:
mvn clean verify
Derlemeyi çalıştırdıktan sonra kod kapsamı raporunu target/site/jacoco/index.html
dosyasında bulabilirsiniz. Bu rapor, kodunuzun birim testlerinizin kapsamı hakkında ayrıntılı bilgi sağlar.
Java birim testi, kodunuzun güvenilirliğini ve doğruluğunu sağlamak için önemli bir uygulamadır. JUnit ve Mockito gibi araçlarla bileşenleriniz için etkili birim testleri ve modeller yazabilirsiniz.
Kod kapsamı analizini Maven ve JaCoCo ile entegre ederek testlerinizin kod tabanınızın önemli bir bölümünü kapsamasını sağlayabilirsiniz. Birim testlerini düzenli olarak test etmek ve sürdürmek, yüksek kaliteli ve sağlam Java uygulamaları üretmenize yardımcı olacaktır.
Bu serinin bir sonraki bölümünde, genel sistemin doğru şekilde çalıştığından emin olmak için farklı bileşenler ve hizmetler arasındaki etkileşimlerin test edilmesini içeren, yazılım testinin kritik bir yönü olan entegrasyon testini inceleyeceğiz.
Entegrasyon testinin heyecan verici dünyasına dalacağımız ikinci bölüm için bizi izlemeye devam edin!