Reference for FluentAssertions - the canonical .NET fluent-assertion library pairable with xUnit / NUnit / MSTest; provides `.Should()` extension API (`.Should().Be()`, `.Should().BeOfType()`, `.Should().Throw()`, `.Should().BeEquivalentTo()` for deep equality, `.Should().Satisfy()` for predicates, `.Should().BeApproximately()` for floats); rich failure messages with object structure visualization. Covers the v8 license change: v8+ is free for open-source and non-commercial use but requires a paid license for commercial use, while v7 remains fully open-source. Use when a .NET test project needs deep object comparison or better failure output than `Assert.X` gives, when assertions must survive a move between xUnit / NUnit / MSTest, or when picking between v7 and v8+ on license grounds.
76
95%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Complete .Should() matcher reference. Core examples live in SKILL.md Step 3; this file is the full catalog. Per fluentassertions.com/introduction.
value.Should().Be(expected);
value.Should().NotBe(expected);
value.Should().BeNull();
value.Should().NotBeNull();
value.Should().BeSameAs(other); // reference equalityn.Should().BeGreaterThan(0);
n.Should().BeLessThanOrEqualTo(100);
d.Should().BeApproximately(3.14, 0.01);s.Should().StartWith("prefix");
s.Should().EndWith("suffix");
s.Should().Contain("substring");
s.Should().Match("*wildcard*");
s.Should().MatchRegex(@"\d+");
s.Should().NotBeNullOrEmpty();list.Should().HaveCount(3);
list.Should().Contain("alice");
list.Should().NotContain("eve");
list.Should().ContainInOrder("alice", "bob");
list.Should().BeEquivalentTo(other); // any order
list.Should().AllSatisfy(x => x.Should().BePositive());result.Should().BeOfType<Success>();
result.Should().BeAssignableTo<IResult>();Action act = () => DoSomething();
act.Should().Throw<ArgumentException>()
.WithMessage("*invalid*")
.Where(e => e.ParamName == "name");
// Async
Func<Task> asyncAct = async () => await DoSomethingAsync();
await asyncAct.Should().ThrowAsync<HttpRequestException>();
// Should NOT throw
act.Should().NotThrow();flag.Should().BeTrue();
flag.Should().BeFalse();
opt.Should().BeNull();
opt.Should().NotBeNull().And.NotBeEmpty();user.Should().Satisfy(u => u.Email.Contains("@") && u.Age >= 18);BeEquivalentTo deep equalityStructural comparison; the most powerful matcher.
var actual = new User { Id = 1, Name = "Alice", Address = new Address { City = "NYC" } };
var expected = new User { Id = 1, Name = "Alice", Address = new Address { City = "NYC" } };
actual.Should().BeEquivalentTo(expected); // passes (deep equal)
// Across different types (record vs class):
var dto = new UserDto { Id = 1, Name = "Alice" };
user.Should().BeEquivalentTo(dto, opts => opts
.Excluding(u => u.PasswordHash)); // ignore field
// With options
actual.Should().BeEquivalentTo(expected, opts => opts
.Excluding(x => x.Timestamp)
.ComparingByMembers<MyType>()
.WithStrictOrdering()
);Options control: Excluding, Including, ComparingByMembers, WithStrictOrdering, WithoutStrictOrdering, IgnoringCyclicReferences.