EasyMock হল একটি mocking framework যা ব্যবহার করে আপনি জাভা কোডের নির্দিষ্ট অংশ (যেমন মেথড কল) মক করতে পারেন। এটি আপনাকে শুধুমাত্র নির্দিষ্ট মেথডগুলির আচরণ নির্ধারণ করার সুযোগ দেয়, অন্যথায় আপনার আসল কোডের মধ্যে মকিং করতে না গিয়ে শূন্য থেকে কাজ করতে সক্ষম হয়।
অনেক সময়, আপনি পুরো অবজেক্টকে মক না করে, কেবল কিছু নির্দিষ্ট মেথড মক করতে চান। EasyMock এ আপনি এটি partial mocking বা mocking only specific methods হিসেবে করতে পারেন।
Partial Mocking বা নির্দিষ্ট মেথড মক করার জন্য EasyMock ব্যবহার করা
EasyMock সাধারণত পুরো অবজেক্ট মক করতে ব্যবহৃত হয়, কিন্তু কিছু সময় spy ব্যবহার করে আপনি partial mocking করতে পারেন। Partial mocking হলো এমন একটি প্রক্রিয়া যেখানে আপনি আসল অবজেক্টের কিছু মেথডকে মক করে, কিন্তু কিছু মেথড আসলভাবে কার্যকরী রেখে দেন। এটি বিশেষভাবে উপকারী যখন আপনার কাছে একটি বড় ক্লাস থাকে এবং আপনি তার কিছু মেথডের আচরণ পরীক্ষা করতে চান।
Partial Mocking এর জন্য spy ব্যবহার করা হয়।
EasyMock এ Partial Mocking এর ধাপসমূহ:
- Spy Object তৈরি করা: EasyMock.spy() মেথড ব্যবহার করে আপনি আসল অবজেক্টের একটি স্পাই তৈরি করতে পারেন।
- Method Stub করা:
expect()মেথড দিয়ে আপনি শুধুমাত্র নির্দিষ্ট মেথডগুলির আচরণ স্টাব (stub) করতে পারেন। - Replay Mode:
replay()মেথড ব্যবহার করে মক অবজেক্টের আচরণ চালু করতে হবে। - Verify:
verify()মেথড ব্যবহার করে নিশ্চিত করতে হবে যে মক মেথডগুলি সঠিকভাবে কল হয়েছে।
উদাহরণ: EasyMock এ Partial Mocking
ধরা যাক, আমাদের একটি PaymentService ক্লাস রয়েছে এবং আমরা চাই PaymentGateway এর processPayment() মেথড মক করতে, কিন্তু getTransactionDetails() মেথডকে আসল অবস্থায় রেখে দিতে। আমরা এখানে EasyMock.spy() ব্যবহার করব যাতে getTransactionDetails() আসলেই কাজ করে, এবং processPayment() মেথডের জন্য কাস্টম স্টাবিং করা হয়।
১. PaymentGateway ক্লাস (Dependency)
public class PaymentGateway {
public boolean processPayment(int amount) {
// Real payment processing logic (e.g., API calls)
return amount > 100;
}
public String getTransactionDetails() {
return "Transaction details from PaymentGateway";
}
}
২. PaymentService ক্লাস (Class Under Test)
public class PaymentService {
private PaymentGateway paymentGateway;
public PaymentService(PaymentGateway paymentGateway) {
this.paymentGateway = paymentGateway;
}
public String makePayment(int amount) {
if (paymentGateway.processPayment(amount)) {
return "Payment successful. " + paymentGateway.getTransactionDetails();
} else {
return "Payment failed";
}
}
}
৩. Unit Test with Partial Mocking using EasyMock
import static org.easymock.EasyMock.*;
import org.junit.Test;
import static org.junit.Assert.*;
public class PaymentServiceTest {
@Test
public void testPartialMocking() {
// Create a real object of PaymentGateway
PaymentGateway realPaymentGateway = new PaymentGateway();
// Create a spy of the real object
PaymentGateway spyPaymentGateway = spy(realPaymentGateway);
// Set up the expectation: mock only the processPayment method
expect(spyPaymentGateway.processPayment(200)).andReturn(true);
// Call the method that is not mocked (getTransactionDetails)
replay(spyPaymentGateway);
// Create PaymentService with the spy object
PaymentService paymentService = new PaymentService(spyPaymentGateway);
// Test the method under test
String result = paymentService.makePayment(200);
// Assert the result
assertEquals("Payment successful. Transaction details from PaymentGateway", result);
// Verify the behavior of the spy object
verify(spyPaymentGateway);
}
@Test
public void testPartialMockingFailure() {
// Create a real object of PaymentGateway
PaymentGateway realPaymentGateway = new PaymentGateway();
// Create a spy of the real object
PaymentGateway spyPaymentGateway = spy(realPaymentGateway);
// Set up the expectation: mock only the processPayment method
expect(spyPaymentGateway.processPayment(50)).andReturn(false);
// Call the method that is not mocked (getTransactionDetails)
replay(spyPaymentGateway);
// Create PaymentService with the spy object
PaymentService paymentService = new PaymentService(spyPaymentGateway);
// Test the method under test
String result = paymentService.makePayment(50);
// Assert the result
assertEquals("Payment failed", result);
// Verify the behavior of the spy object
verify(spyPaymentGateway);
}
}
ব্যাখ্যা:
- Spy Object: আমরা
spy()মেথড ব্যবহার করে আসলPaymentGatewayঅবজেক্টের একটি স্পাই তৈরি করেছি। এতে আমরা শুধুমাত্রprocessPayment()মেথডের জন্য স্টাবিং করেছি, কিন্তুgetTransactionDetails()মেথড আসল অবস্থায় রাখা হয়েছে। - Expectation Setup:
expect()মেথডের মাধ্যমে আমরাprocessPayment(200)মেথডের জন্য একটি কাস্টম আচরণ নির্ধারণ করেছি। যখন এটি কল হবে, তখনtrueফেরত দিবে। - Replay Mode:
replay(spyPaymentGateway)ব্যবহার করে আমরা স্পাই অবজেক্টের আচরণ চালু করেছি। - Method Under Test: আমরা
makePayment()মেথডে200টাকা পাঠিয়ে পরীক্ষণ করেছি, যেখানেprocessPayment()সফলভাবে পেমেন্ট সম্পন্ন করেছে এবংgetTransactionDetails()মেথডটি আসল কার্যকারিতা প্রদান করেছে। - Verification:
verify(spyPaymentGateway)ব্যবহার করে নিশ্চিত করা হয়েছে যেprocessPayment()মেথড সঠিকভাবে কল হয়েছে।
EasyMock এর Partial Mocking এর সুবিধা:
- Efficiency: আপনি প্রয়োজন অনুযায়ী শুধুমাত্র কিছু মেথড মক করতে পারেন, পুরো অবজেক্টকে মক করার প্রয়োজন নেই।
- Flexibility: কিছু মেথডের আচরণ পরীক্ষার জন্য স্টাব করা এবং কিছু মেথডের আসল কার্যকারিতা রাখা সহজ হয়।
- Scalability: যখন আপনার কোডের নির্দিষ্ট অংশ পরীক্ষা করতে হয়, তখন partial mocking দ্রুত টেস্ট তৈরি করতে সাহায্য করে।
EasyMock এর Partial Mocking এর সীমাবদ্ধতা:
- Increased Complexity: কিছু সময় স্পাই অবজেক্ট ব্যবহার করা অতিরিক্ত জটিল হতে পারে, বিশেষ করে যখন মকিং এর জন্য অনেক মেথডের আচরণ নির্ধারণ করতে হয়।
- Not Recommended for Final Methods: EasyMock এর spy() মেথড
finalমেথড বাprivateমেথডের উপর কাজ করে না।
সারাংশ
EasyMock এর মাধ্যমে Partial Mocking বা specific methods mocking করা সম্ভব, যা একটি শক্তিশালী টুল। আপনি মক অবজেক্টের কিছু মেথডের আচরণ স্টাব করে, অন্য কিছু মেথডের আসল কার্যকারিতা বজায় রাখতে পারেন। spy() মেথডের সাহায্যে আপনি শুধু কিছু নির্দিষ্ট মেথডের জন্য কাস্টম স্টাবিং করতে পারেন এবং ইউনিট টেস্টিংয়ে আরো নমনীয়তা এবং দক্ষতা নিশ্চিত করতে পারেন।
Read more