اختبار جافا: الوحدات، التكامل، E2E على المستوى المتقدم

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

اختبار جافا: الوحدات، التكامل، E2E — المستوى المتقدم



في تطوير جافا الحديث، الاختبار ليس مجرد إجراء شكلي، بل هو ممارسة أساسية تضمن استقرار الكود وقابليته للتنبؤ. لقد حلت الاختبارات الأساسية، مثل @Test البسيطة مع Assert.assertEquals، منذ فترة طويلة مكانها استراتيجيات معقدة متعددة الطبقات. في هذه المقالة، سنحلل التقنيات المتقدمة لكل مستوى من هرم الاختبار: الوحدات والتكامل و End-to-End (E2E). ستتعلم كيفية كتابة اختبارات قابلة للصيانة وسريعة وموثوقة تحول كودك إلى آلية مضبوطة جيدًا.



1. اختبارات الوحدات المتقدمة: الكائنات الوهمية (Mocks)، الكائنات البديلة (Stubs)، والمعاملات



تختبر اختبارات الوحدات جزءًا معزولًا من الكود (عادةً فئة أو طريقة واحدة). على المستوى المتقدم، ننتقل من السيناريوهات البسيطة إلى التفاعلات المعقدة والحالات الحدودية. الأداة الرئيسية هنا هي مكتبة Mockito.



1.1. استخدام ArgumentCaptor والاستجابات المعقدة (Answer)



غالبًا ما يكون من الضروري ليس فقط التحقق من استدعاء طريقة، ولكن أيضًا معرفة ما هي الوسائط التي تم تمريرها إليها. لهذا، يتم استخدام ArgumentCaptor.



// مثال: التحقق من إرسال الرسالة الصحيحة إلى الخدمة@ExtendWith(MockitoExtension.class)public class NotificationServiceTest {    @Mock    private EmailSender emailSender;    @InjectMocks    private NotificationService notificationService;

@Test void shouldSendEmailWithCorrectContent() { // ترتيب User user = new User("test@example.com", "Test User"); // تنفيذ notificationService.sendWelcomeEmail(user); // تأكيد ArgumentCaptor<EmailMessage> captor = ArgumentCaptor.forClass(EmailMessage.class); verify(emailSender).send(captor.capture()); EmailMessage capturedMessage = captor.getValue(); assertEquals("test@example.com", capturedMessage.getTo()); assertTrue(capturedMessage.getBody().contains("Test User")); }}


لإنشاء استجابات ديناميكية بناءً على بيانات الإدخال، استخدم واجهة Answer:



@Testvoid testDynamicResponse() {    when(dataRepository.findById(anyLong())).thenAnswer(invocation -> {        Long id = invocation.getArgument(0);        return new DataEntity(id, "Entity with ID: " + id);    });    assertEquals("Entity with ID: 5", dataService.getDataById(5L).getName());}


1.2. الاختبارات المعلمية (JUnit 5)



تسمح المعلمات بتشغيل نفس الاختبار بمجموعات بيانات مختلفة، مما يتجنب تكرار الكود. يوفر JUnit 5 تعليقات توضيحية قوية مثل @CsvSource و @MethodSource.



@ParameterizedTest@CsvSource({    "10, 20, 30",    "0, 0, 0",    "-5, 5, 0"})void testSum(int a, int b, int expectedSum) {    Calculator calculator = new Calculator();    assertEquals(expectedSum, calculator.add(a, b));}


2. اختبار التكامل: العمل مع قاعدة البيانات والخدمات الخارجية



تختبر اختبارات التكامل التفاعل بين مكونات النظام، على سبيل المثال، مع قاعدة بيانات حقيقية أو قوائم انتظار. التحدي الرئيسي هو إدارة حالة البيئة. هنا يأتي دور Testcontainers.



2.1. Testcontainers لقاعدة بيانات معزولة



يقوم Testcontainers بتشغيل حاويات Docker بالبرامج الضرورية (PostgreSQL، Redis، Kafka) مباشرة أثناء الاختبارات، مما يضمن النظافة وقابلية التكرار.



@SpringBootTest@Testcontainersclass UserRepositoryIntegrationTest {

@Container static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15") .withDatabaseName("testdb") .withUsername("test") .withPassword("test");

@DynamicPropertySource static void configureProperties(DynamicPropertyR

المدونات

توصيات الكتب