Mockito المتقدم: ملتقطات المعاملات والكائنات التجسسية
التقط معاملات الطرائق باستخدام ArgumentCaptor، ونفّذ محاكاة جزئية للكائنات الحقيقية باستخدام Mockito.spy
Mockito المتقدم: ملتقطات المعاملات والكائنات التجسسية درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.
ArgumentCaptor: التقاط وسيطات الطرق
تلتقط ArgumentCaptor الوسيطات التي تُمرَّر إلى طريقة تمت محاكاتها، حتى تتمكن من التحقق منها. وتفيد عندما تُنشأ الوسيطة داخل النظام قيد الاختبار ولا يمكنك الوصول إليها مباشرة.
إنشاء ArgumentCaptor واستخدامه
أنشئ أداة التقاط لنوع الوسيطة، ومرّر captor.capture() كمطابق للوسيطات داخل verify()، ثم استدعِ captor.getValue() للحصول على الوسيطة الملتقطة.
@Test
void sends_correct_email() {
ArgumentCaptor<EmailMessage> captor = ArgumentCaptor.forClass(EmailMessage.class);
userService.register(new CreateUserRequest("alice@example.com"));
verify(emailService).send(captor.capture());
EmailMessage msg = captor.getValue();
assertEquals("alice@example.com", msg.getTo());
assertTrue(msg.getSubject().contains("Welcome"));
}التعليمة التوضيحية @Captor
استخدم @Captor مع @ExtendWith(MockitoExtension.class) لتجنب الاستدعاءات المطوّلة لـ ArgumentCaptor.forClass().
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock EmailService emailService;
@Captor ArgumentCaptor<EmailMessage> emailCaptor;
@Test
void captures_email() {
// ...
verify(emailService).send(emailCaptor.capture());
assertEquals("Welcome!", emailCaptor.getValue().getSubject());
}
}التقاط استدعاءات متعددة
استخدم captor.getAllValues() عندما تُستدعى الطريقة عدة مرات. فهي تُعيد قائمة بجميع القيم الملتقطة بترتيب الاستدعاء.
verify(emailService, times(3)).send(emailCaptor.capture());
List<EmailMessage> messages = emailCaptor.getAllValues();
assertEquals(3, messages.size());
assertEquals("Confirmation", messages.get(0).getSubject());Spies في Mockito: المحاكاة الجزئية
تغلّف Mockito.spy() كائنًا حقيقيًا. وتعمل جميع الطرق بشكل طبيعي ما لم تضع لها stubbing صراحةً. استخدمها عندما تحتاج إلى اختبار فئة لديها بعض التبعيات صعبة الاختبار، لكنها تعمل في معظمها بشكل سليم.
List<String> realList = new ArrayList<>();
List<String> spy = Mockito.spy(realList);
spy.add("hello"); // calls real ArrayList.add()
System.out.println(spy.size()); // 1 — real method called
doReturn(42).when(spy).size(); // stub just size()
System.out.println(spy.size()); // 42 — stubbedالتعليمة التوضيحية @Spy
استخدم @Spy مع @ExtendWith(MockitoExtension.class) لإنشاء كائنات spy. ويجب تهيئة الحقل، إما مضمّنًا أو عبر @Spy UserService svc = new UserService(repo);.
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Spy
OrderService orderService = new OrderService(mockRepo, mockEmail);
}إجراء التجسّس على Spring Beans باستخدام @SpyBean
في اختبارات Spring Boot، تغلّف @SpyBean مكوّن Spring موجودًا في كائن spy من Mockito، مع الحفاظ على السلوك الفعلي ما لم تُضبط محاكاته. وتُستخدم مع @SpringBootTest.
@SpringBootTest
class IntegrationTest {
@SpyBean EmailService emailService;
@Test
void order_sends_email() {
orderService.placeOrder(cart);
verify(emailService).sendConfirmation(any());
}
}doReturn مقابل when().thenReturn() مع كائنات spy
مع كائنات spy، استخدم doReturn(value).when(spy).method() بدلًا من when(spy.method()).thenReturn(value). فصيغة when(spy.method()) تستدعي الطريقة الفعلية، مما قد يسبب آثارًا جانبية.
// Correct for spies:
doReturn(List.of()).when(spy).findAll();
// WRONG for spies — calls real findAll() first:
when(spy.findAll()).thenReturn(List.of()); // real method called!التحقق من عدم وجود تفاعلات
استخدم verifyNoInteractions(mock) للتحقق من عدم استدعاء mock مطلقًا، واستخدم verifyNoMoreInteractions(mock) بعد جميع الاستدعاءات المتوقعة لاكتشاف الاستدعاءات غير المتوقعة.
verifyNoInteractions(emailService); // never called
verify(repo).save(any());
verifyNoMoreInteractions(repo); // save() was the only interactionالتحقق باستخدام InOrder
استخدم InOrder للتحقق من استدعاء الطرق التي تمت محاكاتها بترتيب محدد.
InOrder inOrder = inOrder(repo, emailService);
inOrder.verify(repo).save(any());
inOrder.verify(emailService).send(any()); // save happened BEFORE sendمطابقات الوسيطات
ادمج أدوات الالتقاط مع المطابقات: any() وeq() وanyString() وargThat(predicate). إذا استخدمت أي وسيطة مطابقة، فيجب أن تستخدم جميع الوسيطات مطابقات.
verify(repo).save(argThat(user ->
user.getEmail().endsWith("@example.com") &&
user.getStatus() == UserStatus.ACTIVE));تحقق سريع
لماذا نستخدم doReturn بدلًا من when().thenReturn() عند إعداد stubbing لكائن spy؟
مراجعة
تلتقط ArgumentCaptor الوسيطات للتحقق منها بعد الاستدعاء. وتغلّف كائنات spy كائنات حقيقية وتفوض التنفيذ إليها ما لم تُضبط محاكاتها. استخدم doReturn مع كائنات spy، و@SpyBean في اختبارات تكامل Spring. تحقّق من ترتيب الاستدعاءات باستخدام InOrder.
الأسئلة الشائعة
هل درس «Mockito المتقدم: ملتقطات المعاملات والكائنات التجسسية» مجاني؟
نعم — نص درس «Mockito المتقدم: ملتقطات المعاملات والكائنات التجسسية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «Mockito المتقدم: ملتقطات المعاملات والكائنات التجسسية»؟
التقط معاملات الطرائق باستخدام ArgumentCaptor، ونفّذ محاكاة جزئية للكائنات الحقيقية باستخدام Mockito.spy تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «Mockito المتقدم: ملتقطات المعاملات والكائنات التجسسية»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الاختبارات المعلَّمة بالمعاملات باستخدام @CsvSource و@MethodSource
- Mockito المتقدم: ملتقطات المعاملات والكائنات التجسسية
- شرائح اختبار Spring Boot: @WebMvcTest و@DataJpaTest
- Testcontainers: اختبارات تكامل مع قاعدة بيانات حقيقية