হ্যালো হাসিব! এটি আগের লেকচারের কন্টিনিউয়েশন। আগের লেকচারে আমরা Controller এবং CountriesServiceTest-এ Async/Await যুক্ত করেছিলাম। আর এই লেকচারে মূলত একটি অ্যাসাইনমেন্ট সল্যুশন দেখানো হয়েছে, যেখানে পুরো PersonsServiceTest ক্লাসের সবগুলো Unit Test মেথডকে সিঙ্ক্রোনাস থেকে অ্যাসিংক্রোনাস মেথডে কনভার্ট করা হয়েছে।
যেহেতু তুমি অলরেডি আগের লেকচার থেকে এর বেসিক কনসেপ্ট বুঝে গেছো, আমি শুধু এই লেকচারের ইম্পরট্যান্ট টেকঅ্যাওয়েজ (Takeaways) এবং শেষের দিকের সেই ক্রিটিক্যাল এররটি নিয়ে আলোচনা করছি।
📝 Lecture Summary at a Glance
- Full Refactoring:
PersonsServiceTestক্লাসের সব মেথডকেasync Taskএ পরিবর্তন করা হয়েছে এবং সব সার্ভিস কলের আগেawaitবসানো হয়েছে। - Testing Exceptions: আগের লেকচারের মতোই
Assert.ThrowsAsyncএবংawaitব্যবহার করে এক্সেপশন টেস্ট করা হয়েছে। - The “Aha” Moment (No Database Provider Error): সব কোড ঠিক করার পর লেকচারার যখন টেস্ট রান করেন, তখন সব টেস্ট ফেইল করে! এরর মেসেজ ছিল: “No database provider has been configured”.
- The Reason: ইউনিট টেস্ট প্রজেক্টে আমরা SQL Server কনফিগারেশন (
UseSqlServer) দিইনি। কারণ রিয়েল ডাটাবেসে ইউনিট টেস্ট রান করা একটি ব্যাড প্র্যাকটিস (এটি ডাটাবেসকে গারবেজ ডাটা দিয়ে ভরে ফেলে)।
🧠 Comprehensive Breakdown & Deep Dive
১. Refactoring Pattern for xUnit Async Tests [Importance: 8/10]
পুরো লেকচার জুড়ে লেকচারার একটি নির্দিষ্ট প্যাটার্ন ফলো করেছেন। তুমি যখন প্র্যাকটিক্যালি কাজ করবে, তখন এই প্যাটার্নটি মনে রাখলেই হবে:
💻 The Refactoring Pattern:
// ❌ Old Synchronous Test:
[Fact]
public void AddPerson_NullPerson()
{
Assert.Throws<ArgumentNullException>(() =>
{
_personService.AddPerson(null);
});
}
// ✅ New Asynchronous Test (The Pattern):
[Fact]
public async Task AddPerson_NullPerson_Async() // ১. async Task যুক্ত করা
{
// ২. ThrowsAsync এবং await যুক্ত করা
await Assert.ThrowsAsync<ArgumentNullException>(async () => // ৩. ল্যাম্বডাতে async যুক্ত করা
{
await _personService.AddPerson(null); // ৪. সার্ভিস কলে await যুক্ত করা
});
}
২. The Missing Database Provider Error (The Cliffhanger) [Importance: 10/10]
- The “Why”: যখন আমরা ইন-মেমোরি লিস্ট ব্যবহার করতাম (আগের সেকশনগুলোতে), তখন টেস্টগুলো সুন্দর রান করতো। কিন্তু এখন আমরা EF Core এবং
PersonsDbContextব্যবহার করছি। আমাদের মূলCrudExample(Web API) প্রজেক্টেরProgram.cs-এUseSqlServerলেখা আছে, কিন্তুServiceTestsপ্রজেক্ট তো আরProgram.csরান করে না! সে সরাসরি ক্লাস রান করে। তাইDbContextজানেই না যে তাকে কোন ডাটাবেসে কানেক্ট করতে হবে। - Solution Hint: ইউনিট টেস্টের জন্য কখনোই আসল (Real) SQL Server ডাটাবেস ব্যবহার করা উচিত নয়। এর বদলে “In-Memory Database” বা “Mocking (Moq)” ব্যবহার করা হয়। লেকচারার ঠিক এই টপিকটিই পরবর্তী সেকশনের জন্য সাসপেন্স হিসেবে রেখে দিয়েছেন।
🚀 Modern .NET Architecture Notes & Best Practices
১. Do Not Use LINQ Task.WaitAll in Unit Tests:
অনেক সময় জুনিয়র ডেভেলপাররা await ব্যবহার করতে না চাইলে .Result বা Task.WaitAll() ব্যবহার করে শর্টকাট মারে। এটি ইউনিট টেস্টে মারাত্মক “Thread Deadlock” তৈরি করতে পারে। xUnit নিজে থেকেই async Task সাপোর্ট করে, তাই অলওয়েজ স্ট্যান্ডার্ড ফলো করবে।
২. Naming Convention for Async Tests:
লেকচারার মেথডের নামগুলো সেম রেখেছেন, কিন্তু ক্লিন কোড প্র্যাকটিস অনুযায়ী অ্যাসিংক্রোনাস মেথডের শেষে _Async সাফিক্স যুক্ত করা ভালো (যেমন AddPerson_ValidData_ReturnsSuccess_Async)।
এই লেকচারের মাধ্যমে আমাদের EF Core-এর বেসিক ইন্টিগ্রেশন এবং Async/Await এর কাজ শেষ। পরবর্তী সেকশনে এই ইউনিট টেস্টগুলোকে Mock Database দিয়ে কীভাবে পাস করানো যায়, তা নিয়ে আলোচনা শুরু হবে। তুমি রেডি হলে নতুন সেকশনের ট্রান্সক্রিপ্ট দিতে পারো!