Mocking Framework ব্যবহার করে Unit Testing করার মাধ্যমে, আপনি আপনার কোডের নির্দিষ্ট অংশের জন্য প্যারামিটার এবং ডিপেন্ডেন্সি (যেমন সার্ভিস, ডেটাবেস, ওয়েব এপিআই ইত্যাদি) মক বা স্টাব করতে পারেন। এতে আপনার টেস্টগুলি আরও সহজ, দ্রুত এবং নির্ভরযোগ্য হয়, কারণ আপনি external ডিপেন্ডেন্সির উপর নির্ভর না করে কোডের বিভিন্ন অংশ পরীক্ষা করতে পারেন।
এই টিউটোরিয়ালে, Moq (একটি জনপ্রিয় Mocking Framework) ব্যবহার করে Unit Testing-এ Mocking কিভাবে করা হয় এবং কিভাবে টেস্ট ইমপ্লিমেন্টেশন করা যায়, তা আলোচনা করা হবে।
১. Moq Framework ইনস্টলেশন
Moq হলো .NET এর জন্য একটি জনপ্রিয় Mocking Framework। প্রথমে, Moq প্যাকেজ ইনস্টল করতে হবে।
NuGet প্যাকেজ ইনস্টল করা: Visual Studio এর Package Manager Console থেকে নিচের কমান্ডটি রান করুন:
Install-Package Moq- অথবা NuGet Package Manager এর মাধ্যমে Moq প্যাকেজটি ইনস্টল করুন।
২. Mocking Service/Dependency
ধরা যাক, আমাদের একটি ক্লাস রয়েছে যা একটি IDatabaseService ইন্টারফেসের উপর নির্ভরশীল এবং আমরা সেই ক্লাসটির ফাংশন টেস্ট করতে চাই।
১.1 IDatabaseService Interface
public interface IDatabaseService
{
string GetData(int id);
void SaveData(string data);
}
১.2 DataService Class
public class DataService
{
private readonly IDatabaseService _databaseService;
public DataService(IDatabaseService databaseService)
{
_databaseService = databaseService;
}
public string FetchData(int id)
{
return _databaseService.GetData(id);
}
public bool SaveData(string data)
{
_databaseService.SaveData(data);
return true;
}
}
এখানে DataService ক্লাসটি IDatabaseService এর উপর নির্ভরশীল। এখন, আমরা Moq ব্যবহার করে IDatabaseService এর মক (mock) তৈরি করব এবং DataService এর টেস্টিং করব।
৩. Moq ব্যবহার করে Unit Test তৈরি করা
৩.1 Unit Test Framework
Unit Test Framework হিসেবে আমরা xUnit ব্যবহার করব, কিন্তু আপনি NUnit বা MSTest ব্যবহার করলেও কাজ করবে। প্রথমে xUnit এবং Moq প্যাকেজ ইনস্টল করুন।
Install-Package xUnit
Install-Package Moq
৩.2 Mocking DatabaseService এবং Unit Test করা
using Moq;
using Xunit;
namespace DataServiceTests
{
public class DataServiceTest
{
[Fact]
public void FetchData_ReturnsCorrectData()
{
// Arrange
var mockDatabaseService = new Mock<IDatabaseService>();
mockDatabaseService.Setup(service => service.GetData(It.IsAny<int>())).Returns("Mocked Data");
var dataService = new DataService(mockDatabaseService.Object);
// Act
var result = dataService.FetchData(1);
// Assert
Assert.Equal("Mocked Data", result);
}
[Fact]
public void SaveData_CallsSaveMethod()
{
// Arrange
var mockDatabaseService = new Mock<IDatabaseService>();
var dataService = new DataService(mockDatabaseService.Object);
// Act
var result = dataService.SaveData("Test Data");
// Assert
mockDatabaseService.Verify(service => service.SaveData(It.IsAny<string>()), Times.Once);
Assert.True(result);
}
}
}
ব্যাখ্যা:
- Mock: IDatabaseService এর একটি মক অবজেক্ট তৈরি করা হয়েছে।
- Setup(): মক অবজেক্টের জন্য স্টাব (mock) আচরণ নির্ধারণ করা হয়েছে। উদাহরণস্বরূপ, GetData মেথডটি যে কোন ইনপুটের জন্য "Mocked Data" রিটার্ন করবে।
- Verify(): মক অবজেক্টে SaveData মেথডটি একবার কল হয়েছে কিনা তা যাচাই করা হয়েছে।
- Assert.Equal(): FetchData মেথডের আউটপুট এবং প্রত্যাশিত আউটপুটের মধ্যে তুলনা করা হয়েছে।
৪. Mocking Exception Handling
Mocking Framework ব্যবহার করে আপনি এক্সপেকটেড Exceptions-ও মক করতে পারেন, যাতে আপনার টেস্টিং প্রক্রিয়ায় error handling সঠিকভাবে যাচাই করা যায়।
উদাহরণ: Mocking Exception
[Fact]
public void FetchData_ThrowsException_WhenDatabaseFails()
{
// Arrange
var mockDatabaseService = new Mock<IDatabaseService>();
mockDatabaseService.Setup(service => service.GetData(It.IsAny<int>())).Throws(new Exception("Database error"));
var dataService = new DataService(mockDatabaseService.Object);
// Act and Assert
var exception = Assert.Throws<Exception>(() => dataService.FetchData(1));
Assert.Equal("Database error", exception.Message);
}
ব্যাখ্যা:
- Throws(): মক অবজেক্টের GetData মেথডে একটি এক্সপেকটেড Exception সেট করা হয়েছে।
- Assert.Throws(): এখানে নিশ্চিত করা হয়েছে যে, FetchData মেথডটি এক্সপেকটেড এক্সসেপশন ফেলে।
৫. Mocking Callbacks and Verifying Multiple Calls
Moq-তে আপনি মক অবজেক্টের callback-ও সেট করতে পারেন এবং একাধিক কলের জন্য যাচাই করতে পারেন।
উদাহরণ: Callback এবং Multiple Calls
[Fact]
public void SaveData_CallsDatabaseServiceTwice()
{
// Arrange
var mockDatabaseService = new Mock<IDatabaseService>();
mockDatabaseService.Setup(service => service.SaveData(It.IsAny<string>())).Callback<string>((data) =>
{
// Callback logic (could be logging or further verification)
Console.WriteLine($"Saving {data}");
});
var dataService = new DataService(mockDatabaseService.Object);
// Act
dataService.SaveData("Test Data 1");
dataService.SaveData("Test Data 2");
// Assert
mockDatabaseService.Verify(service => service.SaveData(It.IsAny<string>()), Times.Exactly(2));
}
ব্যাখ্যা:
- Callback():
SaveDataমেথডে কলব্যাক ফাংশন সেট করা হয়েছে যা প্রতিটি কলের সাথে কিছু অতিরিক্ত কাজ করতে পারে (যেমন লগিং বা ডেটা যাচাই)। - Verify(): মক অবজেক্টে SaveData মেথডটি মোট ২ বার কল হয়েছে কিনা তা যাচাই করা হয়েছে।
৬. Mocking Asynchronous Methods
Moq ব্যবহার করে আপনি asynchronous methods-ও মক করতে পারবেন। এটি Task বা async/await প্যাটার্ন ব্যবহার করে করা হয়।
উদাহরণ: Mocking Async Methods
public interface IAsyncService
{
Task<string> GetDataAsync(int id);
}
[Fact]
public async Task FetchDataAsync_ReturnsCorrectData()
{
// Arrange
var mockService = new Mock<IAsyncService>();
mockService.Setup(service => service.GetDataAsync(It.IsAny<int>())).ReturnsAsync("Mocked Async Data");
var dataService = new DataService(mockService.Object);
// Act
var result = await dataService.FetchDataAsync(1);
// Assert
Assert.Equal("Mocked Async Data", result);
}
ব্যাখ্যা:
- ReturnsAsync(): মক অবজেক্টে GetDataAsync মেথডের জন্য Task রিটার্ন ভ্যালু সেট করা হয়েছে।
- async/await: অ্যাসিঙ্ক্রোনাস মেথড টেস্ট করার জন্য
awaitব্যবহার করা হয়েছে।
উপসংহার
Mocking Framework এবং Moq ব্যবহার করে Unit Testing প্রক্রিয়া সহজতর এবং আরও কার্যকরী করা যায়। এটি নির্দিষ্ট ডিপেন্ডেন্সি (যেমন সার্ভিস, ডেটাবেস) মক করে, যাতে আপনি শুধুমাত্র কোডের নির্দিষ্ট অংশ পরীক্ষা করতে পারেন। Moq এর মাধ্যমে মক অবজেক্ট তৈরি, স্টাবিং, এক্সপেকটেড এক্সসেপশন হ্যান্ডলিং, এবং অ্যাসিঙ্ক্রোনাস টেস্টিং করা সম্ভব।
Mocking ব্যবহার করে Test Isolation নিশ্চিত করা যায়, যাতে পরীক্ষাটি নির্ভরশীলতা এবং বাইরের সিস্টেমের উপর না থাকে।
Read more