Mocking একটি প্রক্রিয়া যেখানে আপনি একটি অবজেক্টের mock সংস্করণ তৈরি করেন, যাতে প্রকৃত অবজেক্টের আচরণ বা ডেটার উপর নির্ভর না করে, আপনি শুধু নির্দিষ্ট মেথডগুলো পরীক্ষা করতে পারেন। এটি সাধারণত unit testing এ ব্যবহৃত হয়, বিশেষত যখন আপনি এমন একটি কোড টেস্ট করছেন যা বহিরাগত সিস্টেমের উপর নির্ভরশীল (যেমন ডাটাবেস, ওয়েব সার্ভিস, বা ফাইল সিস্টেম)।
JUnit টেস্টিংয়ে Mocking ব্যবহারের মাধ্যমে আপনি সহজেই নির্দিষ্ট ফাংশনালিটি বা কোডের অংশ পরীক্ষা করতে পারেন, যেমন ডিপেনডেন্সি ইনজেকশন ব্যবহার করে।
১. Mocking এর প্রয়োজনীয়তা
প্রকৃত অবজেক্টগুলি এক্সটার্নাল সার্ভিস (ডাটাবেস, API কল, ইত্যাদি) বা সিস্টেমের উপর নির্ভরশীল হলে, তাদেরকে সরাসরি টেস্ট করা খুবই সময়সাপেক্ষ এবং কঠিন হতে পারে। এরকম পরিস্থিতিতে Mocking খুবই গুরুত্বপূর্ণ কারণ:
- Speed: বাহ্যিক সিস্টেমের সাথে যোগাযোগের পরিবর্তে, আপনি মক অবজেক্ট ব্যবহার করে দ্রুত টেস্ট করতে পারেন।
- Isolation: কোডের নির্দিষ্ট অংশকে একা পরীক্ষা করতে সক্ষম হন, বাহ্যিক ডিপেনডেন্সি থেকে বিচ্ছিন্ন হয়ে।
- Control: মক অবজেক্টের মাধ্যমে আপনি কাস্টম আউটপুট নির্ধারণ করতে পারেন এবং এর মাধ্যমে কোডের আচরণ পরীক্ষা করতে পারেন।
২. Mocking কিভাবে কাজ করে?
Mocking একটি উপাদান বা অবজেক্টের আচরণ কৃত্রিমভাবে তৈরি করা। সাধারণত, Mockito বা EasyMock এর মতো লাইব্রেরি ব্যবহার করে Mocking করা হয়। এই লাইব্রেরিগুলি আপনাকে মক অবজেক্ট তৈরি এবং তাদের আচরণ কনফিগার করতে সহায়তা করে।
উদাহরণ:
ধরা যাক, আপনার একটি ক্লাস আছে যা ডাটাবেসে ডাটা সেভ করার জন্য একটি DatabaseService ব্যবহার করে। আপনি যদি DatabaseService টেস্ট করতে চান, তবে আপনাকে আসল ডাটাবেসে সংযোগ স্থাপন করতে হবে, যা অপ্রয়োজনীয় এবং সময়সাপেক্ষ হতে পারে। এখানে Mocking ব্যবহার করে আপনি একটি মক ডাটাবেস অবজেক্ট তৈরি করতে পারেন।
DatabaseService ক্লাস:
public class DatabaseService {
private Database database;
public DatabaseService(Database database) {
this.database = database;
}
public boolean saveData(String data) {
// Data is saved in the database
return database.save(data);
}
}
Database ক্লাস:
public class Database {
public boolean save(String data) {
// Actual logic to save data in a real database
return true;
}
}
এখন, JUnit টেস্টের জন্য Mocking ব্যবহার করা হবে যাতে ডাটাবেসের আসল কোড চালানো না হয়।
DatabaseServiceTest (Mocking Example):
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
public class DatabaseServiceTest {
@Test
public void testSaveData() {
// Create a mock of the Database class
Database mockDatabase = mock(Database.class);
// Define the behavior of the mock object
when(mockDatabase.save("Test Data")).thenReturn(true);
// Create the service with the mock object
DatabaseService databaseService = new DatabaseService(mockDatabase);
// Perform the test
boolean result = databaseService.saveData("Test Data");
// Verify the result
assertTrue(result);
}
}
এখানে:
- mock(Database.class):
Databaseক্লাসের একটি মক অবজেক্ট তৈরি করা হয়েছে। - when(mockDatabase.save("Test Data")).thenReturn(true): মক অবজেক্টের
save()মেথডকে কনফিগার করা হয়েছে যাতে এটিtrueরিটার্ন করে যখন "Test Data" পাস করা হয়। - assertTrue(result): নিশ্চিত করা হয়েছে যে
saveData()মেথড সত্যি রিটার্ন করে, যেহেতু মক ডাটাবেসেরsave()মেথডটিtrueরিটার্ন করছে।
৩. Mocking ব্যবহার করার সময় কিছু টিপস
- Dependencies Mocking: যদি আপনার কোডের অন্য কোনো অংশ ডিপেনডেন্সি হিসেবে অন্য ক্লাস ব্যবহার করে, সেগুলোর মক অবজেক্ট তৈরি করুন। যেমন: API কল, ডাটাবেস, বা ফাইল সিস্টেম।
- Behavior Definition: মক অবজেক্টের আচরণ পরিষ্কারভাবে নির্ধারণ করুন।
when(...).thenReturn(...)ব্যবহার করে মক অবজেক্টের প্রত্যাশিত ফলাফল সেট করুন। Interaction Verification: মক অবজেক্টের সাথে ইন্টারঅ্যাকশন কেমন হচ্ছে তা যাচাই করতে verify() মেথড ব্যবহার করুন।
উদাহরণ:
verify(mockDatabase).save("Test Data");Use Stubbing for Return Values: মক অবজেক্ট থেকে রিটার্নের জন্য ডিফল্ট বা কাস্টম মান ব্যবহার করুন।
when(mockDatabase.save("Test Data")).thenReturn(false); // Custom value- Limitations: Mocking শুধুমাত্র তখনই ব্যবহার করুন যখন বাহ্যিক ডিপেনডেন্সি টেস্টের জন্য প্রয়োজনীয় না হয়। Mocking ব্যবহার করা বেশি হলে কোডের জটিলতা বেড়ে যেতে পারে।
৪. Mocking এর সুবিধা
- Isolated Testing: মক অবজেক্ট ব্যবহার করে আপনি আপনার টেস্টের জন্য বাইরের সিস্টেমের উপর নির্ভরশীল না হয়ে কোডের নির্দিষ্ট অংশ পরীক্ষা করতে পারেন।
- Increased Speed: বাহ্যিক সিস্টেমে ডেটা পাঠানো বা প্রাপ্ত করার পরিবর্তে, মক অবজেক্ট ব্যবহার করলে টেস্ট দ্রুত সম্পন্ন হয়।
- Error Isolation: মক অবজেক্টের মাধ্যমে আপনি সহজে ডিপেনডেন্সি বা কোডের সমস্যাগুলি চিহ্নিত করতে পারেন।
৫. Mocking কখন প্রয়োজন?
Mocking তখন প্রয়োজনীয় হয়ে ওঠে যখন:
- আপনি বাহ্যিক সিস্টেমের উপর নির্ভরশীল কোড টেস্ট করছেন, যেমন ডাটাবেস, রিমোট সার্ভিস, ফাইল সিস্টেম ইত্যাদি।
- আপনি একটি নির্দিষ্ট কোড ফ্লো বা লজিক পরীক্ষা করতে চান এবং বাহ্যিক সিস্টেমের আচরণ আপনার পরীক্ষার সাথে প্রভাবিত না হোক তা নিশ্চিত করতে চান।
- বাহ্যিক সিস্টেমের কার্যক্রম ধীরগতির কারণে, আপনার টেস্ট আরও দ্রুত করতে চান।
উপসংহার
Mocking একটি গুরুত্বপূর্ণ টুল যা আপনাকে unit testing এর সময় বাহ্যিক ডিপেনডেন্সি থেকে বিচ্ছিন্ন হয়ে শুধুমাত্র কোডের নির্দিষ্ট অংশ পরীক্ষা করতে সাহায্য করে। এটি দ্রুত টেস্টিং, নির্ভরযোগ্যতা এবং সিস্টেমের পারফরম্যান্সে কোনো প্রভাব না ফেলতে ব্যবহৃত হয়। JUnit টেস্টিংয়ে Mockito ব্যবহার করে আপনি Mocking প্রক্রিয়া খুব সহজে এবং কার্যকরীভাবে বাস্তবায়ন করতে পারেন।
Read more