হ্যালো হাসিব! এটি আগের লেকচারের কন্টিনিউয়েশন। আগের লেকচারে আমরা FluentAssertions এর বেসিক কিছু কনসেপ্ট শিখেছিলাম এবং PersonsServiceTest এর অর্ধেক টেস্ট মেথডে তা অ্যাপ্লাই করেছিলাম। এই লেকচারটিতে মূলত বাকি অর্ধেক টেস্ট মেথডকে FluentAssertions এ কনভার্ট করা হয়েছে।

যেহেতু তুমি অলরেডি আগের লেকচার থেকে Should().Be(), Should().ThrowAsync() এবং Should().BeEquivalentTo() এর কনসেপ্ট বুঝে গেছো, আমি শুধু এই লেকচারের ইম্পরট্যান্ট নতুন কিছু টেকঅ্যাওয়েজ (Takeaways) নিয়ে আলোচনা করছি।

📝 Lecture Summary at a Glance

  • Collection Filtering: কোনো লিস্ট ফিল্টার বা সার্চ করার পর তার ভেতরের ডাটাগুলো ঠিক আছে কিনা তা চেক করার জন্য Should().OnlyContain(lambda) ব্যবহার করা হয়েছে।
  • Sorting Verification: ম্যানুয়ালি ডাটা সর্ট করে ইকুয়ালিটি চেক করার বদলে, FluentAssertions এর ডিরেক্ট Should().BeInDescendingOrder(property) মেথড ব্যবহার করা হয়েছে।
  • Boolean Verification: True বা False চেক করার জন্য Should().BeTrue() এবং Should().BeFalse() ব্যবহার করা হয়েছে।
  • Implicit Typing (var): ডেলিগেট ডিফাইন করার সময় লম্বা Func<Task> না লিখে var ব্যবহার করার ট্রিক দেখানো হয়েছে।

🧠 Comprehensive Breakdown & Deep Dive

১. Verifying Filtered Collections (OnlyContain) [Importance: 9/10]

  • The “Why”: যখন তুমি ডাটাবেসে “MA” দিয়ে সার্চ করো, তখন তোমাকে মেকশিওর করতে হবে যে রিটার্ন হওয়া লিস্টের সবগুলো আইটেমের নামের মধ্যেই “MA” আছে।
  • The Fluent Way: এর জন্য লুপ চালানোর কোনো দরকার নেই। FluentAssertions এর OnlyContain মেথডটি খুবই চমৎকারভাবে এই কাজ করে দেয়।

💻 Code Implementation:

// ❌ Old Way (Looping through the list):
/*
foreach(var person in personResponseListFromSearch)
{
    Assert.Contains("MA", person.PersonName, StringComparison.OrdinalIgnoreCase);
}
*/
 
// ✅ Fluent Way:
personResponseListFromSearch.Should().OnlyContain(temp => 
    temp.PersonName.Contains("MA", StringComparison.OrdinalIgnoreCase)
);
 

২. Verifying Sorted Collections (BeInDescendingOrder) [Importance: 10/10]

  • The “Why”: xUnit-এ সর্টিং চেক করার জন্য সাধারণত অরিজিনাল লিস্টকে মেমোরিতে .OrderByDescending() দিয়ে সর্ট করতে হয় এবং তারপর ডাটাবেস থেকে আসা লিস্টের সাথে ইকুয়ালিটি চেক করতে হয়। এটি অনেক সময়সাপেক্ষ।
  • The Fluent Way: FluentAssertions সরাসরি লিস্টের এলিমেন্টগুলো লিনিয়ারলি চেক করে দেখতে পারে যে তারা কোনো স্পেসিফিক প্রপার্টির ওপর বেস করে সাজানো আছে কিনা।

💻 Code Implementation:

// ❌ Old Way:
// var sortedList = personListFromAdd.OrderByDescending(p => p.PersonName).ToList();
// actualList.Should().BeEquivalentTo(sortedList);
 
// ✅ Fluent Way (Super clean!):
personListFromSort.Should().BeInDescendingOrder(temp => temp.PersonName);
 

৩. The var Trick for Exception Testing [Importance: 8/10]

  • The “Why”: আগের লেকচারে আমরা অ্যাসিংক্রোনাস এক্সেপশন টেস্ট করার জন্য Func<Task> action = async () => { ... } লিখতাম। কিন্তু C#-এ টাইপ ইনফারেন্স (Type Inference) এর সুবিধা নিলে কোড আরও ক্লিন হয়।

💻 Code Implementation:

// ❌ Old Way:
// Func<Task> action = async () => await _personsService.UpdatePerson(updateRequest);
 
// ✅ Fluent Way with 'var':
var action = async () => 
{
    await _personsService.UpdatePerson(updateRequest);
};
 
await action.Should().ThrowAsync<ArgumentException>();
 

(নোট: মডার্ন C# এ কম্পাইলার নিজে থেকেই বুঝতে পারে যে async () => একটি Func<Task> রিপ্রেজেন্ট করছে, তাই var লেখাটা সেফ)।


🚀 Modern Testing Strategy Summary

হাসিব, এখন পর্যন্ত আমরা টেস্টিংয়ের যে টুলগুলো শিখেছি, একটি প্রোডাকশন গ্রেড প্রজেক্টে এগুলো একসাথে কীভাবে কাজ করে তার একটি সামারি নিচে দিলাম:

  1. Test Runner: xUnit (টেস্ট রান করা এবং ডেটা ইনপুট দেওয়া [Fact], [Theory]).
  2. Data Generator: AutoFixture (ডামি মডেল অবজেক্ট তৈরি করার জন্য _fixture.Create<T>()).
  3. Mocking Framework: Moq (এক্সটার্নাল ডিপেন্ডেন্সি যেমন DbContext বা External API কে ফেক বা মক করার জন্য).
  4. Assertion Library: FluentAssertions (টেস্টের রেজাল্ট ন্যাচারাল ল্যাঙ্গুয়েজে ভেরিফাই করার জন্য .Should().Be()).

এই কম্বিনেশনটি বর্তমান .NET ইন্ডাস্ট্রির (বিশেষ করে Clean Architecture প্রজেক্টের) Standard Testing Stack। তুমি তোমার “Chatrabash” প্রজেক্টে এই পুরো স্ট্যাকটি ইউজ করলে টেস্ট কোডের কোয়ালিটি অনেক হাই হবে।

পরবর্তী লেকচারগুলোতে টেস্টিংয়ের অন্য কোনো টপিক বা কনসেপ্ট নিয়ে আলোচনা হতে পারে। তুমি রেডি হলে পরের ট্রান্সক্রিপ্টটি দিতে পারো!