হ্যালো হাসিব! আজকের লেকচারটি মূলত FluentAssertions এর একটি কমপ্লিট “Cheat Sheet” বা রেফারেন্স গাইড।

আগের লেকচারগুলোতে আমরা হাতে-কলমে FluentAssertions ব্যবহার করেছিলাম। এই লেকচারটিতে লেকচারার বিভিন্ন সিনারিওতে (Numbers, Strings, Collections, Exceptions) কোন মেথডটি ব্যবহার করতে হবে, তার একটি বিস্তারিত লিস্ট বা ডিকশনারি দিয়েছেন।

চলো পুরো লেকচারটির একটি কুইক সামারি এবং ইম্পরট্যান্ট পয়েন্টগুলো দেখে নিই।

📝 Lecture Summary at a Glance

  • Core Rule: FluentAssertions-এ সবসময় Actual Value আগে লিখতে হয় এবং এরপর .Should() চেইন করে রিকোয়ারমেন্ট অনুযায়ী মেথড ডাকতে হয়।
  • Null & Booleans: .Should().BeNull(), .Should().BeTrue() ইত্যাদি।
  • Strings & Numbers: .Should().BeNullOrEmpty(), .Should().BePositive(), .Should().BeInRange(min, max) ইত্যাদি।
  • Collections: সাইজ চেক করতে .Should().HaveCount(5), সর্টিং চেক করতে .Should().BeInAscendingOrder() এবং ডাটা চেক করতে .Should().ContainInOrder()
  • Object Equality: .Should().BeEquivalentTo() ব্যবহার করলে এটি অবজেক্টের টাইপ (Class Name) না দেখে ভেতরের প্রপার্টির ভ্যালুগুলো ম্যাচ করে (যদি Equals মেথড ওভাররাইড করা না থাকে)।

🧠 Comprehensive Breakdown & Deep Dive

১. Object and Collection Equality (BeEquivalentTo) [Importance: 10/10]

  • The “Why”: এটি ইন্টারভিউ এবং রিয়েল-ওয়ার্ল্ড প্রজেক্টের জন্য খুবই ইম্পরট্যান্ট একটি কনসেপ্ট।

  • How it works: তুমি যখন দুটি অবজেক্ট (বা লিস্ট) এর মধ্যে .Should().BeEquivalentTo() ব্যবহার করো, তখন FluentAssertions কীভাবে বোঝে যে তারা সেম?

  • Scenario A (Custom Equals): তুমি যদি তোমার মডেলে (যেমন PersonResponse) Equals মেথড ওভাররাইড করে থাকো, তবে সে ওই মেথডটি কল করবে।

  • Scenario B (Default Object Graph): তুমি যদি Equals ওভাররাইড না করো, তবে সে ইন্টারনালি রিফ্লেকশন (Reflection) ব্যবহার করে দুটি অবজেক্টের সবগুলো প্রপার্টি (যেমন Name, Age) ধরে ধরে চেক করবে।

  • The Magic: সবচেয়ে মজার ব্যাপার হলো, তুমি যদি একটি Person অবজেক্টের সাথে একটি Student অবজেক্টের BeEquivalentTo চেক করো, আর তাদের দুজনের প্রপার্টিগুলোর নাম ও ভ্যালু হুবহু সেম হয়, তবে টেস্ট পাস করবে! কারণ এটি টাইপ চেক করে না, ডাটা চেক করে।

২. Type Assertions (BeOfType vs BeAssignableTo) [Importance: 8/10]

  • The “Why”: যখন তুমি চেক করতে চাও যে রিটার্ন হওয়া অবজেক্টটি আসলে কোন ক্লাসের।
  • BeOfType<T>(): এটি স্ট্রিক্টলি চেক করে যে অবজেক্টটি একদম ওই ক্লাসেরই হতে হবে। (যেমন: person.Should().BeOfType<Person>())
  • BeAssignableTo<T>(): এটি চেক করে যে অবজেক্টটি ওই ক্লাসের বা তার কোনো চাইল্ড (Derived/Inherited) ক্লাসের কিনা। (যেমন: student.Should().BeAssignableTo<Person>() পাস করবে কারণ Student হলো Person এর চাইল্ড)।

৩. Number & Range Assertions [Importance: 7/10]

  • The “Why”: বয়স, দাম বা ক্যালকুলেশনের রেজাল্ট চেক করার জন্য।
  • Methods: * age.Should().BePositive()
  • price.Should().BeGreaterThanOrEqualTo(10)
  • discount.Should().BeInRange(10, 50) (১০ থেকে ৫০ এর ভেতর কিনা)

৪. Collection Specific Assertions [Importance: 9/10]

  • The “Why”: ডাটাবেস থেকে আসা লিস্ট চেক করার জন্য এই মেথডগুলো রেগুলার xUnit এর চেয়ে বহুগুণ শক্তিশালী।
  • HaveCount(x): লিস্টে ঠিক কয়টি আইটেম আছে।
  • ContainInOrder(x, y): শুধু যে আইটেমগুলো থাকতে হবে তা নয়, বরং তুমি যে সিরিয়ালে দিয়েছো ঠিক সেই সিরিয়ালেই থাকতে হবে।
  • OnlyHaveUniqueItems(): লিস্টে কোনো ডুপ্লিকেট আইটেম থাকা যাবে না।

🚀 Modern Testing Best Practices (Cheat Sheet Expansion)

হাসিব, লেকচারার যে চিট-শিট দিয়েছেন, তার সাথে তুমি তোমার “Chatrabash” প্রজেক্টের জন্য নিচের প্রো-টিপসগুলোও মাথায় রাখতে পারো:

১. Combining Multiple Assertions (The And Keyword): FluentAssertions-এর সবচেয়ে সুন্দর দিক হলো তুমি একাধিক কন্ডিশন And দিয়ে চেইন করতে পারো। এতে কোড দেখতে একদম সেন্টেন্সের মতো লাগে।

// উদাহরণ: ইউজারের লিস্ট চেক করা
usersList.Should().NotBeEmpty()
         .And.HaveCount(5)
         .And.OnlyHaveUniqueItems()
         .And.BeInAscendingOrder(u => u.Name);
 

২. Structuring your Tests (Arrange, Act, Assert): সবসময় তোমার টেস্ট মেথডগুলোকে এই তিনটি ব্লকে ভাগ করে লিখবে। এতে কোড রিডাবিলিটি বাড়ে।

[Fact]
public async Task GetUser_ReturnsUser()
{
    // Arrange (AutoFixture, Mocking setup)
    var expectedUser = _fixture.Create<UserResponse>();
    
    // Act (Calling the actual method)
    var actualUser = await _userService.GetUser(1);
    
    // Assert (FluentAssertions)
    actualUser.Should().BeEquivalentTo(expectedUser);
}
 

এটি মূলত একটি থিওরেটিক্যাল লেকচার ছিল। তুমি চাইলে এই চিট-শিটটি তোমার নোটস (Notion/Obsidian) এ সেভ করে রাখতে পারো। পরবর্তী লেকচার থেকে আমরা হয়তো নতুন কোনো সেকশন বা টপিক (যেমন Repository Pattern) শুরু করবো। তুমি রেডি হলে নতুন ট্রান্সক্রিপ্টটি দিতে পারো!