xUnit unit testing best practices in C#: AAA pattern, naming and FIRST

xUnit Testing & CI/CD in .NET November 13, 2026 csharp

AAA: Arrange (setup), Act (one action), Assert (check the result).

csharp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// ======================================================================
// Q: What makes a good unit test? How do you structure it?
//
// - AAA: Arrange (setup), Act (one action), Assert (check the result).
// - One behavior per test, with a name that describes it:
//   Method_Scenario_ExpectedResult or a sentence (Cannot_place_an_empty_order).
// - FIRST: Fast, Isolated (no shared state), Repeatable (same result
//   everywhere), Self-validating (pass/fail without human inspection), Timely.
// - Test behavior (result, state, observable side effects), not implementation
//   details. A refactoring that does not change behavior should not break tests.
// - Unit tests for domain logic and rules. Integration tests for the database,
//   HTTP, serialization, DI (Q13).
// ======================================================================

public class OrderTests
{
    [Fact]
    public void Place_with_lines_moves_order_to_placed_and_raises_event()
    {
        // Arrange
        var order = new OrderBuilder().WithLine("PIP-100", 2, unitPrice: 189m).Build();

        // Act
        order.Place();

        // Assert
        Assert.Equal(OrderStatus.Placed, order.Status);
        Assert.Single(order.DomainEvents.OfType<OrderPlaced>());
    }
}