A brittle test runs quickly and may catch regressions, but fails when implementation changes without changing observable behavior. Its false positives expose coupling to the system under test’s internal details: it verifies how the result is produced rather than what the system does. section 4.4 section 5.2
Reduce brittleness by applying these rules:
- Assert observable behavior instead of private methods, internal state, call sequences, or exact implementation artifacts. section 5.2 section 11.1
- Use mocks for unmanaged dependencies whose interactions are observable externally; mocking other dependencies can produce brittle tests. section 9.0
- Treat difficult testing of a complex private method as evidence of dead code or a missing abstraction, not as a reason to expose the method. section 11.1
Exact SQL versus observable behavior
A test that asserts `SELECT * FROM dbo.[User] WHERE UserID = 5` turns red when equivalent SQL changes whitespace, qualification, selected columns, or parameterization. It therefore protects against SQL-generation regressions while resisting legitimate refactoring poorly. section 4.4
Listing 4.6. Test verifying which SQL statement is executed
public class UserRepository
{
public User GetById(int id)
{
/* ... */
}
public string LastExecutedSqlStatement { get; set; }
}
[Fact]
public void GetById_executes_correct_SQL_code()
{
var sut = new UserRepository();
User user = sut.GetById(5);
Assert.Equal(
"SELECT * FROM dbo.[User] WHERE UserID = 5",
sut.LastExecutedSqlStatement);
}
Inspect the repository test that verifies the exact SQL statement executed, the canonical brittle-test example. section 4.4


