Good Code
The good version names the missing-review behavior, performs one action, and asserts the null result.
Lesson 10
Structure tests so setup, behavior, and assertions are separate enough for reviewers to see the contract under test.
[Fact]
public async Task FindAsyncReturnsNullWhenReviewIsMissing()
{
var repository = new FakeReviewRepository();
var service = new ReviewService(repository);
// One act step makes the behavior under test easy to see.
ReviewDto? result = await service.FindAsync(Guid.NewGuid(), CancellationToken.None);
Assert.Null(result);
}[Fact]
public async Task TestReviewService()
{
var service = new ReviewService(new FakeReviewRepository());
await service.FindAsync(Guid.NewGuid(), CancellationToken.None);
await service.FindAsync(Guid.NewGuid(), CancellationToken.None);
// No assertion means the test only proves the calls did not throw.
}The good version names the missing-review behavior, performs one action, and asserts the null result.
The bad version has a vague test name, calls the method twice, and contains no assertion. It can pass while the method returns the wrong value.