EasyMock হলো একটি শক্তিশালী জাভা লাইব্রেরি যা ইউনিট টেস্টিংয়ের জন্য মকিং (Mocking) এবং স্টাবিং (Stubbing) করার কাজকে সহজ করে তোলে। EasyMock এর Record-Replay Model টেস্টিং প্রক্রিয়ায় একটি মৌলিক ধারণা, যা মক অবজেক্টের আচরণ নির্ধারণ এবং পরে সেই আচরণ প্রয়োগ করার জন্য ব্যবহৃত হয়। এই মডেলটি মক অবজেক্ট তৈরির দুটি প্রধান ধাপ নির্ধারণ করে: রেকর্ড (Record) এবং রিপ্লে (Replay)।
Record-Replay Model এর মৌলিক ধারণা
Record-Replay Model দুটি ধাপে বিভক্ত:
- Record Phase: এই ধাপে আপনি মক অবজেক্টের প্রত্যাশিত আচরণ নির্ধারণ করেন। অর্থাৎ, কোন মেথড কখন এবং কী রিটার্ন করবে তা স্টাব করা হয়।
- Replay Phase: এই ধাপে মক অবজেক্টকে ব্যবহৃত করা হয় এবং পূর্বে নির্ধারিত আচরণ অনুযায়ী মেথডগুলো কল করা হয়।
Record Phase
Record Phase এ, আপনি মক অবজেক্টের প্রত্যাশিত মেথড কল এবং তাদের রিটার্ন ভ্যালু বা এক্সেপশন নির্ধারণ করেন। এখানে আপনি আসল মেথডের কোন কার্যকলাপ সম্পাদন করবেন না, বরং শুধুমাত্র মেথড কলের আচরণ নির্ধারণ করবেন।
Replay Phase
Replay Phase এ, মক অবজেক্টকে ব্যবহার করা হয় এবং পূর্বে নির্ধারিত মেথড কলগুলোকে সম্পাদন করা হয়। এই সময়, EasyMock নিশ্চিত করে যে মেথডগুলো ঠিকভাবে কল হয়েছে কিনা এবং প্রত্যাশিত ফলাফল প্রদান করেছে কিনা।
উদাহরণ: Record-Replay Model ব্যবহার করে EasyMock
ধরা যাক, আমাদের একটি Calculator ইন্টারফেস আছে যা দুটি মেথড প্রদান করে: add(int a, int b) এবং subtract(int a, int b)।
Step 1: Maven Dependency (যদি Maven ব্যবহার করেন)
আপনার প্রোজেক্টে EasyMock যোগ করতে, pom.xml ফাইলে নিচের ডিপেনডেন্সি যুক্ত করুন:
<dependencies>
<!-- EasyMock Dependency -->
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>4.3</version> <!-- সর্বশেষ ভার্সন অনুযায়ী পরিবর্তন করুন -->
<scope>test</scope>
</dependency>
<!-- JUnit Dependency -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Step 2: Calculator ইন্টারফেস তৈরি
public interface Calculator {
int add(int a, int b);
int subtract(int a, int b);
}
Step 3: Record Phase - মক অবজেক্টের প্রত্যাশিত আচরণ নির্ধারণ
import org.easymock.EasyMock;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class EasyMockRecordReplayTest {
@Test
public void testCalculator() {
// Step 1: মক অবজেক্ট তৈরি
Calculator mockCalculator = EasyMock.createMock(Calculator.class);
// Step 2: Record Phase - মেথড কলের প্রত্যাশিত আচরণ নির্ধারণ
EasyMock.expect(mockCalculator.add(2, 3)).andReturn(5);
EasyMock.expect(mockCalculator.subtract(5, 3)).andReturn(2);
// Step 3: Record Phase শেষ, এখন Replay Phase শুরু
EasyMock.replay(mockCalculator);
// Step 4: Replay Phase - মক অবজেক্ট ব্যবহার করা
int additionResult = mockCalculator.add(2, 3);
int subtractionResult = mockCalculator.subtract(5, 3);
// Step 5: ফলাফল যাচাই করা
assertEquals(5, additionResult);
assertEquals(2, subtractionResult);
// Step 6: Verification Phase - নিশ্চিত করা যে সমস্ত মেথড প্রত্যাশিতভাবে কল হয়েছে
EasyMock.verify(mockCalculator);
}
}
Step 4: টেস্ট রান এবং আউটপুট
এই টেস্ট রান করলে কোনও ত্রুটি ছাড়াই পাস করবে, কারণ মক অবজেক্টের প্রত্যাশিত মেথড কলগুলো সঠিকভাবে সম্পাদন হয়েছে।
আউটপুট:
JUnit version 4.13.1
.
Time: 0.005
OK (1 test)
Advanced Example: Exception Handling সহ Record-Replay Model
ধরা যাক, Calculator ইন্টারফেসের divide(int a, int b) মেথড আছে যা যদি b শূন্য হয় তবে একটি IllegalArgumentException ছুঁড়ে দেয়।
Calculator ইন্টারফেস আপডেট
public interface Calculator {
int add(int a, int b);
int subtract(int a, int b);
int divide(int a, int b) throws IllegalArgumentException;
}
টেস্ট কেস: Divide Method এর Exception Handling
import org.easymock.EasyMock;
import org.junit.Test;
public class EasyMockExceptionTest {
@Test(expected = IllegalArgumentException.class)
public void testDivideMethodWithException() {
// Step 1: মক অবজেক্ট তৈরি
Calculator mockCalculator = EasyMock.createMock(Calculator.class);
// Step 2: Record Phase - মেথড কলের প্রত্যাশিত আচরণ নির্ধারণ
EasyMock.expect(mockCalculator.divide(10, 0)).andThrow(new IllegalArgumentException("Cannot divide by zero"));
// Step 3: Replay Phase শুরু
EasyMock.replay(mockCalculator);
// Step 4: মক অবজেক্টের মেথড কল যা এক্সেপশন ছুঁড়ে দেবে
mockCalculator.divide(10, 0);
// Step 5: Verification Phase - নিশ্চিত করা যে মেথড কল হয়েছে
EasyMock.verify(mockCalculator);
}
}
আউটপুট:
JUnit version 4.13.1
.
Time: 0.003
OK (1 test)
Verification Phase এর গুরুত্ব
Verification Phase নিশ্চিত করে যে মক অবজেক্টটি প্রত্যাশিত মেথড কলগুলো সঠিকভাবে সম্পাদন করেছে কিনা। এটি টেস্টের সঠিকতা এবং সঙ্গতিতা যাচাই করতে গুরুত্বপূর্ণ।
Verification এর সুবিধাসমূহ:
- আচরণ যাচাই: মক অবজেক্টের মেথডগুলো প্রত্যাশিত আচরণ অনুসারে কল হয়েছে কিনা তা নিশ্চিত করে।
- কতবার কল হয়েছে: মেথডটি কতবার কল হয়েছে তা যাচাই করে, যেমন একবার, একাধিকবার ইত্যাদি।
- আর্গুমেন্ট যাচাই: মেথডে সঠিক আর্গুমেন্টের সাথে কল হয়েছে কিনা তা নিশ্চিত করে।
সহজ ধাপসমূহে Record-Replay Model ব্যবহার
- মক অবজেক্ট তৈরি:
EasyMock.createMock()দিয়ে মক অবজেক্ট তৈরি করুন। - Record Phase:
- প্রত্যাশিত মেথড কল নির্ধারণ করুন।
- প্রত্যাশিত রিটার্ন ভ্যালু বা এক্সেপশন নির্ধারণ করুন।
- Replay Phase:
EasyMock.replay()মেথড ব্যবহার করে মক অবজেক্টকে রিপ্লে মোডে নিয়ে যান।- মক অবজেক্টের মেথডগুলো কল করুন এবং ফলাফল পরীক্ষা করুন।
- Verification Phase:
EasyMock.verify()মেথড ব্যবহার করে নিশ্চিত করুন যে মেথডগুলো প্রত্যাশিতভাবে কল হয়েছে।
সারাংশ
Record-Replay Model EasyMock এর একটি মৌলিক ধারণা যা মক অবজেক্টের আচরণ নির্ধারণ এবং পরীক্ষা করার জন্য ব্যবহৃত হয়। এটি টেস্টিং প্রক্রিয়াকে সহজ এবং কার্যকরী করে তোলে, বিশেষ করে যখন আপনি নির্দিষ্ট মেথড কল এবং তাদের আচরণ পরীক্ষা করতে চান। Record Phase এ মক অবজেক্টের প্রত্যাশিত আচরণ নির্ধারণ করা হয় এবং Replay Phase এ সেই আচরণ প্রয়োগ করা হয়। Verification Phase টেস্টের সঠিকতা নিশ্চিত করে।
EasyMock এর Record-Replay Model ব্যবহার করে আপনি আপনার ইউনিট টেস্টগুলোকে আরো শক্তিশালী এবং নির্ভরযোগ্য করতে পারেন, যা আপনার কোডের মান এবং কার্যকারিতা বৃদ্ধি করে।
EasyMock একটি শক্তিশালী Java মকিং লাইব্রেরি যা ইউনিট টেস্টিংয়ের জন্য মক অবজেক্ট তৈরি করতে ব্যবহৃত হয়। Record-Replay Model হল EasyMock এর মূল ধারণা, যার মাধ্যমে মক অবজেক্ট তৈরি, আচরণ নির্ধারণ এবং তারপরে সেই আচরণ চালানোর (replay) প্রক্রিয়া করা হয়। এই মডেলটি আপনাকে টেস্টের মধ্যে নির্দিষ্ট মেথড কলগুলির আচরণ নির্ধারণ করতে এবং পরে তাদের সঠিকতা যাচাই করতে সাহায্য করে।
Record-Replay Model এর মাধ্যমে EasyMock মক অবজেক্টের জন্য কার্যকরী টেস্টিং করা হয় এবং এর মাধ্যমে মক অবজেক্টের ওপর নির্ভরশীল কোডের আচরণ সঠিকভাবে পরীক্ষা করা যায়।
1. Record-Replay Model এর স্তরসমূহ
Record-Replay মডেলটি দুটি প্রধান পর্যায়ে বিভক্ত:
- Record Phase (রেকর্ড ফেজ)
- Replay Phase (রিপ্লে ফেজ)
1.1 Record Phase (রেকর্ড ফেজ)
এটি হল সেই ধাপ যেখানে আপনি মক অবজেক্ট তৈরি করেন এবং তার ওপর কিছু আচরণ (expectations) নির্ধারণ করেন। আপনি মক অবজেক্টের জন্য এমন কিছু আচরণ সংজ্ঞায়িত করেন যা পরীক্ষার সময় ঘটবে। এই পর্যায়ে, আপনি মক অবজেক্টের কোনো মেথড কল এবং তার প্রত্যাশিত রিটার্ন ভ্যালু বা ব্যতিক্রমগুলো সেটআপ করেন।
Record Phase এর সময় আপনি expect() এবং andReturn() এর মতো EasyMock মেথডগুলো ব্যবহার করে নির্দিষ্ট আচরণ বা ভ্যালু নির্ধারণ করেন।
Record Phase Example:
// Creating a mock object
DatabaseService mockDatabaseService = EasyMock.createMock(DatabaseService.class);
// Setting expectations for mock object
EasyMock.expect(mockDatabaseService.fetchData()).andReturn("Mock Data");
// Activate the mock object
EasyMock.replay(mockDatabaseService);
এখানে, fetchData() মেথডের জন্য আমরা একটি expectation সেট করেছি যে এটি "Mock Data" রিটার্ন করবে।
1.2 Replay Phase (রিপ্লে ফেজ)
Replay Phase এর সময় মক অবজেক্টটি সক্রিয় হয়ে ওঠে এবং এটি টেস্টের মধ্যে ব্যবহৃত হয়। এই পর্যায়ে, আপনি মক অবজেক্টের মেথড কল করবেন এবং EasyMock নিশ্চিত করবে যে পূর্বে সেট করা expectations অনুসারে আচরণ হচ্ছে।
Replay Phase এর সময় আপনি মক অবজেক্টের মেথডগুলি চালাবেন এবং সেগুলি ঠিকমতো কাজ করছে কিনা তা যাচাই করবেন।
Replay Phase Example:
// Method under test using mock object
String result = mockDatabaseService.fetchData(); // Will return "Mock Data"
// Verify that expectations are met
EasyMock.verify(mockDatabaseService);
এখানে, fetchData() মেথড কল করা হয়েছে এবং এটি পূর্বে নির্ধারিত প্রত্যাশা অনুযায়ী "Mock Data" রিটার্ন করবে। তারপর, verify() মেথড ব্যবহার করে আমরা যাচাই করেছি যে, সব মেথড কল সঠিকভাবে ঘটেছে কিনা।
2. Record-Replay Model এর Advantages
2.1 Test Isolation
Record-Replay মডেলটি টেস্টিংকে আলাদা করে, কারণ এটি বাইরের সিস্টেমের (যেমন ডাটাবেস, নেটওয়ার্ক সার্ভিস) উপর নির্ভরশীলতা সরিয়ে দেয় এবং মক অবজেক্টের মাধ্যমে সেগুলির আচরণ সিমুলেট করা হয়।
2.2 Behavior Simulation
এই মডেলটি আপনাকে মক অবজেক্টের সঠিক আচরণ পরীক্ষা করতে সাহায্য করে। আপনি যখন কোনো মেথড কল করেন, তখন আপনি নিশ্চিত হতে পারেন যে এটি পূর্বনির্ধারিত আচরণ অনুযায়ী কাজ করবে।
2.3 Increased Test Coverage
Record-Replay মডেল আপনাকে বিশেষ পরিস্থিতিতে কোডের আচরণ পরীক্ষার সুযোগ দেয়, যা সত্যিকারের ডিপেনডেন্সির মাধ্যমে পরীক্ষিত হতে পারে না।
2.4 Faster Test Execution
মক অবজেক্ট ব্যবহার করলে আপনি বাইরের সিস্টেমের সাথে সংযোগ না করে দ্রুত টেস্ট চালাতে পারেন, যা সিস্টেমের পারফরম্যান্স উন্নত করতে সহায়তা করে।
3. Record-Replay Model এর Workflow
Record-Replay মডেলটি সাধারণত নিম্নলিখিত পদক্ষেপে কাজ করে:
- Mock Object Creation: প্রথমে আপনি
EasyMock.createMock()মেথড ব্যবহার করে মক অবজেক্ট তৈরি করেন। - Expectations Setup: এরপর আপনি expect() এবং andReturn() ব্যবহার করে মক অবজেক্টের আচরণ নির্ধারণ করেন।
- Replay Phase: তারপর,
replay()মেথড ব্যবহার করে মক অবজেক্টটি সক্রিয় করা হয়, এবং এটি টেস্টের মধ্যে ব্যবহার করা হয়। - Test Execution: মক অবজেক্টের মেথড কল করা হয় এবং তার রিটার্ন ভ্যালু বা ব্যতিক্রম যাচাই করা হয়।
- Verification: টেস্টের শেষে,
verify()মেথড ব্যবহার করে মক অবজেক্টের সকল কল সঠিকভাবে হয়েছে কিনা তা নিশ্চিত করা হয়।
4. Record-Replay Model এর Example
এখানে একটি উদাহরণ দেখানো হলো যেখানে আমরা একটি UserService ক্লাসের মেথড মক করে তার আচরণ পরীক্ষা করছি।
Example: UserService এবং Record-Replay Model
import org.easymock.EasyMock;
import org.junit.Test;
import static org.easymock.EasyMock.*;
public class EasyMockRecordReplayExample {
// Interface to be mocked
public interface UserService {
String getUserInfo(int userId);
}
@Test
public void testUserService() {
// Step 1: Create mock object
UserService mockUserService = createMock(UserService.class);
// Step 2: Set expectations (Record Phase)
expect(mockUserService.getUserInfo(1)).andReturn("User 1 Info");
expect(mockUserService.getUserInfo(2)).andReturn("User 2 Info");
// Step 3: Activate mock (Replay Phase)
replay(mockUserService);
// Step 4: Test the mock behavior
System.out.println(mockUserService.getUserInfo(1)); // Expected output: User 1 Info
System.out.println(mockUserService.getUserInfo(2)); // Expected output: User 2 Info
// Step 5: Verify that expectations were met
verify(mockUserService);
}
}
ব্যাখ্যা:
- Step 1:
createMock()দিয়েUserServiceএর মক অবজেক্ট তৈরি করা হয়েছে। - Step 2:
expect()ব্যবহার করেgetUserInfo()মেথডের জন্য কিছু প্রত্যাশিত আচরণ সেট করা হয়েছে। - Step 3:
replay()মেথড ব্যবহার করে মক অবজেক্টটি সক্রিয় করা হয়েছে। - Step 4: মক অবজেক্টের মেথড কল করা হয়েছে এবং সেগুলির রিটার্ন ভ্যালু যাচাই করা হয়েছে।
- Step 5:
verify()মেথড ব্যবহার করে নিশ্চিত করা হয়েছে যে, সমস্ত প্রত্যাশিত মেথড কল সঠিকভাবে ঘটেছে।
Record-Replay Model হল EasyMock এর একটি মূল কনসেপ্ট যা মক অবজেক্ট তৈরির এবং টেস্টিংয়ের একটি পরিষ্কার ও কার্যকরী প্রক্রিয়া প্রদান করে। এটি expect(), andReturn(), replay(), এবং verify() মেথডের মাধ্যমে মক অবজেক্টের আচরণ টেস্ট করতে সহায়তা করে। Record-Replay Model এর মাধ্যমে টেস্টিংয়ের সময় নির্ভরশীলতা হ্রাস পায় এবং টেস্টের গতি বৃদ্ধি পায়, যা সফটওয়্যার উন্নয়ন প্রক্রিয়াকে আরও দক্ষ করে তোলে।
EasyMock এর Record Mode কি?
EasyMock এর Record Mode হল এমন একটি মোড যেখানে আপনি মক অবজেক্টের behavior (আচরণ) বা expectations (প্রত্যাশা) ডিফাইন করতে পারেন। যখন আপনি expect() মেথড ব্যবহার করেন, তখন আপনি যেটি প্রত্যাশা করছেন, সেটি Record Mode এ সুনির্দিষ্ট করা হয়। এর মানে হল যে আপনি মক অবজেক্টের মেথড কলগুলি আগে থেকেই জানিয়ে দেন যে কোন ইনপুট প্রদান করলে কেমন আউটপুট আশা করা হবে। এরপর এই প্রত্যাশিত আচরণগুলি replay mode-এ যাচাই করা হয়।
EasyMock এর Record Mode এবং Replay Mode এর মধ্যে পার্থক্য:
- Record Mode: এটি expect() মেথড ব্যবহার করে মক অবজেক্টের আচরণ (behavior) নির্ধারণ করা হয়। যখন আপনি মক অবজেক্টের মেথড কল করেন, তখন আপনি কি আশা করছেন, তা এখানে ডিফাইন করা হয়।
- Replay Mode: যখন আপনি মক অবজেক্টে মেথড কল করেন, তখন এটি আগেরভাবে ডিফাইন করা আচরণ অনুসরণ করে এবং আপনি নিশ্চিত হতে পারেন যে আপনার কোড প্রত্যাশিতভাবে কাজ করছে।
Record Mode এ Behavior ডিফাইন করার উদাহরণ
ধরা যাক, আপনার একটি Service ইন্টারফেস রয়েছে, যার মধ্যে দুটি মেথড greet(String name) এবং farewell(String name) রয়েছে। এই মেথডগুলির জন্য behavior record mode-এ ডিফাইন করতে হবে।
Step 1: Service Interface
public interface Service {
String greet(String name);
String farewell(String name);
}
Step 2: Test Class with Record Mode Behavior
এখন, আপনি EasyMock ব্যবহার করে মক অবজেক্ট তৈরি করবেন এবং greet() এবং farewell() মেথডের জন্য behavior ডিফাইন করবেন।
import org.easymock.EasyMock;
import org.junit.Test;
import static org.junit.Assert.*;
public class EasyMockRecordModeTest {
@Test
public void testServiceBehaviorInRecordMode() {
// Creating a mock object of Service using EasyMock
Service serviceMock = EasyMock.createMock(Service.class);
// Setting up expectations in Record Mode (defining behavior)
EasyMock.expect(serviceMock.greet("John")).andReturn("Hello, John!"); // Behavior for greet method
EasyMock.expect(serviceMock.farewell("John")).andReturn("Goodbye, John!"); // Behavior for farewell method
// Activating the mock (moving to Replay Mode)
EasyMock.replay(serviceMock);
// Calling the methods and checking the expected results
String greetResult = serviceMock.greet("John");
String farewellResult = serviceMock.farewell("John");
// Verifying the results
assertEquals("Hello, John!", greetResult);
assertEquals("Goodbye, John!", farewellResult);
// Verifying that the expected methods were called
EasyMock.verify(serviceMock);
}
}
ব্যাখ্যা:
- EasyMock.createMock(Service.class): এটি
Serviceইন্টারফেসের একটি মক অবজেক্ট তৈরি করে। - EasyMock.expect(): এটি
greet("John")এবংfarewell("John")মেথডের জন্য প্রত্যাশা (behavior) নির্ধারণ করে। - EasyMock.replay(): এটি মক অবজেক্টে record mode থেকে replay mode-এ চলে আসে এবং মক অবজেক্টের আচরণ কার্যকর হয়।
- assertEquals(): এটি যাচাই করে যে মক অবজেক্টের মেথড কলের ফলাফল প্রত্যাশিত আউটপুটের সাথে মিলে।
- EasyMock.verify(): এটি নিশ্চিত করে যে প্রত্যাশিত মেথডগুলো সঠিকভাবে মক অবজেক্টে কল হয়েছে।
Multiple Expectations সেট করা
আপনি একাধিক expectations (অথবা behavior) একটি মক অবজেক্টের জন্য সেট করতে পারেন, যাতে একাধিক মেথড কলের প্রত্যাশা তৈরি করা যায়। উদাহরণস্বরূপ:
@Test
public void testMultipleExpectations() {
// Creating a mock object of Service
Service serviceMock = EasyMock.createMock(Service.class);
// Setting multiple expectations (behaviors) in Record Mode
EasyMock.expect(serviceMock.greet("Alice")).andReturn("Hello, Alice!");
EasyMock.expect(serviceMock.farewell("Alice")).andReturn("Goodbye, Alice!");
EasyMock.expect(serviceMock.greet("Bob")).andReturn("Hello, Bob!");
// Activating the mock (moving to Replay Mode)
EasyMock.replay(serviceMock);
// Testing the mock behavior
String greetAlice = serviceMock.greet("Alice");
String farewellAlice = serviceMock.farewell("Alice");
String greetBob = serviceMock.greet("Bob");
// Verifying the results
assertEquals("Hello, Alice!", greetAlice);
assertEquals("Goodbye, Alice!", farewellAlice);
assertEquals("Hello, Bob!", greetBob);
// Verifying that the expected methods were called
EasyMock.verify(serviceMock);
}
ব্যাখ্যা:
- এখানে আমরা Alice এবং Bob এর জন্য আলাদা আলাদা greet() এবং farewell() মেথডের জন্য প্রত্যাশা তৈরি করেছি।
- Multiple expectations তৈরি করার মাধ্যমে, আপনি বিভিন্ন ইনপুটের জন্য পৃথক পৃথক আচরণ নির্ধারণ করতে পারেন।
Exception Throwing in Record Mode
আপনি যদি কোনো মেথডে exception থ্রো করতে চান, তবে expect() এবং andThrow() মেথড ব্যবহার করতে পারেন।
উদাহরণ: Exception থ্রো করা
@Test(expected = IOException.class)
public void testExceptionInRecordMode() throws IOException {
// Creating a mock object of Service
Service serviceMock = EasyMock.createMock(Service.class);
// Setting up the expectation to throw an exception
EasyMock.expect(serviceMock.greet("Alice")).andThrow(new IOException("Error in greeting"));
// Activating the mock
EasyMock.replay(serviceMock);
// Calling the method to check if the exception is thrown
serviceMock.greet("Alice");
// Verifying that the expected methods were called
EasyMock.verify(serviceMock);
}
ব্যাখ্যা:
- andThrow(): এটি নির্ধারণ করে যে যখন
greet("Alice")মেথড কল হবে, তখন একটি IOException থ্রো হবে। - @Test(expected = IOException.class): JUnit এ expected exception নির্ধারণ করে, যাতে পরীক্ষার সময় IOException আসলেই থ্রো হয়েছে কিনা তা যাচাই করা যায়।
সারাংশ
EasyMock এর Record Mode হল সেই মোড যেখানে আপনি মক অবজেক্টের expectations বা behavior ডিফাইন করেন। এটি মক অবজেক্টের মেথড কলের জন্য প্রত্যাশিত আউটপুট এবং আচরণ নির্ধারণ করতে সহায়তা করে। expect() এবং andReturn() মেথডের মাধ্যমে আপনি মেথড কলের প্রত্যাশিত ফলাফল নির্ধারণ করতে পারেন, এবং andThrow() ব্যবহার করে আপনি মক অবজেক্ট থেকে exception থ্রো করতে পারেন। এরপর, replay() মোডে এই প্রত্যাশাগুলি যাচাই করা হয় এবং verify() দিয়ে নিশ্চিত করা হয় যে সঠিক মেথড কল হয়েছে।
EasyMock একটি জনপ্রিয় mocking framework যা Java টেস্টিংয়ের জন্য ব্যবহৃত হয়। যখন আমরা মক অবজেক্ট তৈরি করি, তখন মক অবজেক্টগুলি expectation সেট করতে সাহায্য করে, তবে এই এক্সপেকটেশনগুলি শুধুমাত্র তখন কার্যকর হয় যখন আমরা মক অবজেক্টে replay mode এ চলে আসি। Replay Mode হল সেই অবস্থা যেখানে মক অবজেক্টের জন্য নির্ধারিত expectations কার্যকরী হয়, এবং আসল অবজেক্টের মতো আচরণ করতে শুরু করে।
এই টিউটোরিয়ালে আমরা EasyMock এ replay mode এবং মক এক্সিকিউশন সম্পর্কে বিস্তারিত আলোচনা করব।
1. Replay Mode কী?
Replay Mode হল EasyMock এর একটি অবস্থা যেখানে আপনি মক অবজেক্টে যে expectations সেট করেছেন, তা কার্যকরী হবে। এটি নিশ্চিত করে যে মক অবজেক্টটি সেই আচরণে কাজ করবে যেটি আপনি টেস্টের আগে সংজ্ঞায়িত করেছেন। replay() মেথডটি কল করার পর, মক অবজেক্টটি expectations অনুযায়ী কার্যকরী হয়।
2. Replay Mode এ Mock Execution Process
মক অবজেক্টে expectations সেট করা হয় এবং পরে replay() মেথড ব্যবহার করে এই এক্সপেকটেশনগুলো কার্যকর করা হয়। মক অবজেক্টে replay() কল করার আগে, এক্সপেকটেশনগুলো expect() এবং andReturn() দিয়ে সংজ্ঞায়িত করা হয়।
3. Replay Mode Flow
- Create Mock Object: প্রথমে মক অবজেক্ট তৈরি করা হয়।
- Set Expectations: মক অবজেক্টের উপর এক্সপেকটেশন নির্ধারণ করা হয় (যেমন, কোন মেথড কল হবে এবং তা কী রিটার্ন করবে)।
- Activate Replay Mode: replay() মেথড ব্যবহার করে মক অবজেক্টের replay mode সক্রিয় করা হয়, যাতে এটি expectations অনুসারে আচরণ করে।
- Execute Mocks: মক অবজেক্টে নির্ধারিত এক্সপেকটেশন অনুযায়ী মেথডগুলি কল করা হয়।
- Verify Mocks: মক অবজেক্টের উপর নির্ধারিত এক্সপেকটেশন সঠিকভাবে কাজ করেছে কিনা তা যাচাই করার জন্য verify() মেথড ব্যবহার করা হয়।
4. Replay Mode Example in EasyMock
ধরা যাক, আমাদের একটি CalculatorService ক্লাস আছে এবং আমরা তার add() মেথডের জন্য একটি মক অবজেক্ট তৈরি করতে চাই। আমরা চাই যে, যদি দুটি সংখ্যা যোগ করা হয়, তাহলে এটি সঠিকভাবে ফলাফল প্রদান করবে।
4.1. Basic Example of Replay Mode
import org.easymock.EasyMock;
import org.junit.Test;
import static org.junit.Assert.*;
interface CalculatorService {
int add(int a, int b);
}
public class ReplayModeExample {
@Test
public void testAddMethod() {
// 1. Create mock object
CalculatorService calculatorMock = EasyMock.createMock(CalculatorService.class);
// 2. Set expectations
EasyMock.expect(calculatorMock.add(10, 20)).andReturn(30); // expect add() to return 30 when 10 and 20 are added
// 3. Activate replay mode
EasyMock.replay(calculatorMock);
// 4. Execute mock method
int result = calculatorMock.add(10, 20);
// 5. Verify the result
assertEquals(30, result);
// 6. Verify that the mock method was called correctly
EasyMock.verify(calculatorMock);
}
}
ব্যাখ্যা:
- Create Mock Object: EasyMock.createMock(CalculatorService.class) ব্যবহার করে আমরা CalculatorService এর জন্য মক অবজেক্ট তৈরি করেছি।
- Set Expectations: EasyMock.expect() এবং andReturn() এর মাধ্যমে আমরা add(10, 20) মেথডের জন্য এক্সপেকটেশন সেট করেছি, যাতে এটি 30 রিটার্ন করে।
- Activate Replay Mode: EasyMock.replay(calculatorMock) মেথডটি কল করে আমরা মক অবজেক্টে replay mode সক্রিয় করেছি।
- Execute Mocks: এরপর আমরা add(10, 20) মেথড কল করেছি, যা মক অবজেক্টে নির্ধারিত এক্সপেকটেশন অনুসারে 30 রিটার্ন করবে।
- Verify Mocks: EasyMock.verify(calculatorMock) ব্যবহার করে নিশ্চিত করেছি যে add(10, 20) মেথডটি ঠিকভাবে কল হয়েছে।
আউটপুট:
Test passed successfully.
5. Multiple Expectations and Replay Mode
আমরা একাধিক মেথড কলের জন্য একাধিক এক্সপেকটেশনও সেট করতে পারি। নিচে একটি উদাহরণ দেওয়া হল যেখানে দুটি মেথডের জন্য এক্সপেকটেশন সেট করা হয়েছে।
5.1. Multiple Expectations Example
import org.easymock.EasyMock;
import org.junit.Test;
import static org.junit.Assert.*;
interface CalculatorService {
int add(int a, int b);
int subtract(int a, int b);
}
public class MultipleExpectationsExample {
@Test
public void testMultipleMethodCalls() {
// 1. Create mock object
CalculatorService calculatorMock = EasyMock.createMock(CalculatorService.class);
// 2. Set expectations for multiple method calls
EasyMock.expect(calculatorMock.add(10, 20)).andReturn(30);
EasyMock.expect(calculatorMock.subtract(20, 10)).andReturn(10);
// 3. Activate replay mode
EasyMock.replay(calculatorMock);
// 4. Execute mock methods
int addResult = calculatorMock.add(10, 20);
int subtractResult = calculatorMock.subtract(20, 10);
// 5. Verify the results
assertEquals(30, addResult);
assertEquals(10, subtractResult);
// 6. Verify that the mock methods were called correctly
EasyMock.verify(calculatorMock);
}
}
ব্যাখ্যা:
- এখানে CalculatorService ইন্টারফেসে দুটি মেথড রয়েছে: add() এবং subtract()।
- EasyMock.expect() এর মাধ্যমে দুটি মেথডের জন্য এক্সপেকটেশন সেট করা হয়েছে।
- replay() মেথডটি সক্রিয় করার পর, আমরা add(10, 20) এবং subtract(20, 10) মেথড কল করেছি এবং তাদের ফলাফল যাচাই করেছি।
- verify() মেথডের মাধ্যমে নিশ্চিত করেছি যে মক অবজেক্টে নির্ধারিত এক্সপেকটেশন অনুযায়ী মেথডগুলি কল হয়েছে।
আউটপুট:
Test passed successfully.
6. Exception Handling with Replay Mode
EasyMock এ exception handling এর জন্য আমরা andThrow() মেথড ব্যবহার করে মক অবজেক্টে এক্সেপশন থ্রো করতে পারি। Replay Mode এর সময় এই এক্সেপশনটি কার্যকরী হবে।
6.1. Exception Handling in Replay Mode Example
import org.easymock.EasyMock;
import org.junit.Test;
import static org.junit.Assert.*;
class PaymentService {
public void processPayment(int amount) throws IllegalArgumentException {
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive");
}
System.out.println("Payment of " + amount + " processed.");
}
}
public class ExceptionHandlingExample {
@Test(expected = IllegalArgumentException.class)
public void testProcessPaymentWithException() {
// Create mock object
PaymentService paymentServiceMock = EasyMock.createMock(PaymentService.class);
// Set expectation to throw exception when amount is zero or negative
EasyMock.expect(paymentServiceMock.processPayment(0)).andThrow(new IllegalArgumentException("Amount must be positive"));
// Activate replay mode
EasyMock.replay(paymentServiceMock);
// Execute mock method
paymentServiceMock.processPayment(0);
// Verify the mock interaction
EasyMock.verify(paymentServiceMock);
}
}
ব্যাখ্যা:
- PaymentService ক্লাসে processPayment() মেথডে IllegalArgumentException থ্রো করা হয় যদি পরিমাণ শূন্য বা নেতিবাচক হয়।
- EasyMock.expect() এবং andThrow() ব্যবহার করে আমরা এক্সেপশন থ্রো করার এক্সপেকটেশন সেট করেছি।
- @Test(expected = IllegalArgumentException.class) অ্যানোটেশনটি নিশ্চিত করেছে যে processPayment(0) কল করার সময় IllegalArgumentException থ্রো হবে।
আউটপুট:
java.lang.IllegalArgumentException: Amount must be positive
Replay Mode হল EasyMock এর একটি গুরুত্বপূর্ণ অংশ, যেখানে মক অবজেক্টের জন্য নির্ধারিত expectations কার্যকরী হয়। replay() মেথড ব্যবহার করার মাধ্যমে মক অবজেক্টের expectations সক্রিয় করা হয়, এবং verify() মেথডের মাধ্যমে যাচাই করা হয় যে, মক অবজেক্টে কল হওয়া মেথডগুলি সঠিকভাবে কাজ করেছে।
- Exception Handling: আপনি andThrow() মেথড ব্যবহার করে exceptions মক করতে পারেন।
- Multiple Expectations: একাধিক মেথড এবং এক্সপেকটেশন সেট করা সম্ভব।
- Replay Mode: মক অবজেক্টে নির্ধারিত expectations কার্যকরী করার জন্য replay() মেথড ব্যবহৃত হয়।
এটি আপনার unit testing কে আরও নমনীয় এবং শক্তিশালী করতে সাহায্য করে।
EasyMock এর মাধ্যমে mock objects তৈরি এবং ব্যবস্থাপনা করা সহজ। একটি mock object এর আচরণ সঠিকভাবে পরীক্ষার জন্য verification mode ব্যবহার করা হয়, যাতে নিশ্চিত করা যায় যে mock objects এর মেথডগুলো সঠিকভাবে নির্ধারিত সংখ্যায় কল হয়েছে। EasyMock এ, মেথডের কলের সংখ্যা এবং আচরণ যাচাই করার জন্য কিছু verification মেথড ব্যবহার করা হয়।
এই গাইডে, আমরা EasyMock এর মাধ্যমে verification mode এ মেথড কলের সংখ্যা নিশ্চিত করার পদ্ধতি আলোচনা করব, এবং দেখব কীভাবে exactly(), atLeastOnce(), atMost() এবং times() ব্যবহার করে মেথড কল নিশ্চিত করা যায়।
1. Verification Mode এর সাথে Method Call নিশ্চিত করা
EasyMock এর verification mode ব্যবহার করে, আপনি mock object এর মেথডগুলির কলের সংখ্যা এবং আচরণ নিশ্চিত করতে পারেন। এখানে কিছু প্রধান verification মেথডের আলোচনা করা হয়েছে:
- exactly(n): এই মেথডটি নিশ্চিত করে যে নির্দিষ্ট মেথডটি exactly
nবার কল হয়েছে। - atLeastOnce(): এই মেথডটি নিশ্চিত করে যে মেথডটি কমপক্ষে একবার কল হয়েছে।
- atMost(n): এই মেথডটি নিশ্চিত করে যে মেথডটি সর্বোচ্চ
nবার কল হয়েছে। - times(n): এটি নিশ্চিত করে যে মেথডটি
nবার কল হয়েছে।
Example: Verification Mode
ধরা যাক, আমাদের একটি PaymentService ইন্টারফেস রয়েছে, যা processPayment মেথডটি প্রক্রিয়া করে এবং আমাদের টেস্টে আমরা চাই এটি একটি নির্দিষ্ট সংখ্যক বার কল হয়েছে কিনা তা নিশ্চিত করতে।
import static org.easymock.EasyMock.*;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class PaymentServiceTest {
private PaymentService mockPaymentService;
@Before
public void setUp() {
// Mock object তৈরি
mockPaymentService = createMock(PaymentService.class);
}
@Test
public void testProcessPayment_ExactlyOnce() {
// mock object এর প্রত্যাশিত আচরণ নির্ধারণ
expect(mockPaymentService.processPayment(100.0)).andReturn(true);
// Mock সক্রিয় করা
replay(mockPaymentService);
// মেথড কল
mockPaymentService.processPayment(100.0);
// verify() মেথডে নিশ্চিত করা যে এটি একবার কল হয়েছে
verify(mockPaymentService); // exactly once
}
@Test
public void testProcessPayment_AtLeastOnce() {
// mock object এর প্রত্যাশিত আচরণ নির্ধারণ
expect(mockPaymentService.processPayment(100.0)).andReturn(true);
// Mock সক্রিয় করা
replay(mockPaymentService);
// মেথড কল (কমপক্ষে একবার কল করা হবে)
mockPaymentService.processPayment(100.0);
mockPaymentService.processPayment(100.0);
// verify() মেথডে নিশ্চিত করা যে এটি কমপক্ষে একবার কল হয়েছে
verify(mockPaymentService); // at least once
}
@Test
public void testProcessPayment_AtMost() {
// mock object এর প্রত্যাশিত আচরণ নির্ধারণ
expect(mockPaymentService.processPayment(100.0)).andReturn(true);
// Mock সক্রিয় করা
replay(mockPaymentService);
// মেথড কল (সর্বাধিক একবার কল করা হবে)
mockPaymentService.processPayment(100.0);
mockPaymentService.processPayment(100.0);
// verify() মেথডে নিশ্চিত করা যে এটি সর্বাধিক একবার কল হয়েছে
verify(mockPaymentService); // at most once
}
@Test
public void testProcessPayment_Times() {
// mock object এর প্রত্যাশিত আচরণ নির্ধারণ
expect(mockPaymentService.processPayment(100.0)).andReturn(true);
// Mock সক্রিয় করা
replay(mockPaymentService);
// মেথড কল (একবার)
mockPaymentService.processPayment(100.0);
// verify() মেথডে নিশ্চিত করা যে এটি একবার কল হয়েছে
verify(mockPaymentService); // called once
}
}
Explanation:
- exactly(n):
verify(mockPaymentService)ব্যবহার করা হয়েছে যেখানে নিশ্চিত করা হয়েছে যে processPayment(100.0) একবার কল হয়েছে।
- atLeastOnce():
- এখানে processPayment মেথডটি কমপক্ষে একবার কল করা হয়েছে, এবং verify(mockPaymentService) এর মাধ্যমে নিশ্চিত করা হয়েছে যে এটি একাধিকবার কল করা হয়েছে।
- atMost(n):
- এখানে processPayment মেথডটি সর্বোচ্চ একবার কল করা হয়েছে এবং
verify(mockPaymentService)এর মাধ্যমে নিশ্চিত করা হয়েছে যে এটি একবারের বেশি কল হয়নি।
- এখানে processPayment মেথডটি সর্বোচ্চ একবার কল করা হয়েছে এবং
- times(n):
- এখানে processPayment(100.0) মেথডটি একবার কল হওয়া নিশ্চিত করা হয়েছে।
2. Verification Mode এর ব্যবহার:
exactly(n)
exactly(n) ব্যবহার করা হয় যখন আপনি নিশ্চিত করতে চান যে একটি mock মেথড নির্দিষ্ট সংখ্যক বার কল হয়েছে।
expect(mockPaymentService.processPayment(100.0)).andReturn(true);
replay(mockPaymentService);
mockPaymentService.processPayment(100.0);
verify(mockPaymentService); // Exactly once
atLeastOnce()
atLeastOnce() ব্যবহার করা হয় যখন আপনি নিশ্চিত করতে চান যে একটি mock মেথড কমপক্ষে একবার কল হয়েছে। এটি যখন আপনার কাছে একাধিক কল আসবে এবং আপনি চান যে মেথডটি অন্তত একবার কল হোক, তখন এটি ব্যবহার করা হয়।
expect(mockPaymentService.processPayment(100.0)).andReturn(true);
replay(mockPaymentService);
mockPaymentService.processPayment(100.0);
mockPaymentService.processPayment(100.0);
verify(mockPaymentService); // At least once
atMost(n)
atMost(n) ব্যবহার করা হয় যখন আপনি নিশ্চিত করতে চান যে একটি mock মেথড সর্বাধিক n বার কল হয়েছে।
expect(mockPaymentService.processPayment(100.0)).andReturn(true);
replay(mockPaymentService);
mockPaymentService.processPayment(100.0);
mockPaymentService.processPayment(100.0);
verify(mockPaymentService); // At most once
times(n)
times(n) ব্যবহার করা হয় যখন আপনি নিশ্চিত করতে চান যে একটি mock মেথড n বার কল হয়েছে।
expect(mockPaymentService.processPayment(100.0)).andReturn(true);
replay(mockPaymentService);
mockPaymentService.processPayment(100.0);
verify(mockPaymentService); // Called exactly once
EasyMock এর verification mode এর মাধ্যমে আপনি mock objects-এর মেথডগুলো সঠিকভাবে কতবার কল হয়েছে তা নিশ্চিত করতে পারেন। আপনি exactly(n), atLeastOnce(), atMost(n), এবং times(n) মেথডের মাধ্যমে mock method calls এর সংখ্যা যাচাই করতে পারেন। এই verification techniques আপনাকে unit tests এর কার্যকারিতা নিশ্চিত করতে সাহায্য করবে এবং আপনার কোডের সঠিকতা ও নির্ভুলতা পরীক্ষা করতে সুবিধা দিবে।
Read more