👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
Unit Testing Anti-Pattern: Exposing Private State

Unit Testing Anti-Pattern: Exposing Private State

Testing

7 Articles

Improve

Table of Contents

  1. What we gonna do?
  2. Why we gonna do?
  3. How we gonna do?
  4. Summary

What we gonna do?

Exposing private state for unit testing is a common anti-pattern. Private fields and methods should remain encapsulated, and tests should verify the observable behavior of the system rather than its internal state.

Why we gonna do?

Making private fields accessible solely for testing introduces tight coupling between tests and implementation details. This can lead to brittle tests that break due to minor code changes, even when functionality remains intact. A well-structured test suite should interact with the system in the same way as production code to ensure maintainability and reliability.

How we gonna do?

Instead of exposing private state, tests should validate behavior through public methods. Consider the following example of a Member class:

public class Member
{
    private MembershipLevel _level = MembershipLevel.Standard;
    
    public void Upgrade()
    {
        _level = MembershipLevel.Premium;
    }
    
    public decimal GetDiscount()
    {
        return _level == MembershipLevel.Premium ? 0.1m : 0m;
    }
}

public enum MembershipLevel
{
    Standard,
    Premium
}
            

The Upgrade() method changes the internal state, affecting the discount calculation. Instead of exposing the private field, tests should validate the expected behavior:

[Fact]
public void New_Member_Should_Have_No_Discount()
{
    var member = new Member();
    Assert.Equal(0m, member.GetDiscount());
}

[Fact]
public void Upgraded_Member_Should_Get_10_Percent_Discount()
{
    var member = new Member();
    member.Upgrade();
    Assert.Equal(0.1m, member.GetDiscount());
}
            

These tests confirm correct behavior without exposing internal state.

Summary

Exposing private state for testing leads to unnecessary coupling and fragile tests. Instead, unit tests should focus on verifying observable behavior. By designing tests that align with production interactions, we ensure better maintainability and robustness of the system.

👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
  • Testing
  • Anti Pattern
  • Unit Testing