Test Driven Development–Testing Private Values

Jon Galloway and I are embarking on the next phase of our Full Stack projectMadScientist_iStock_000000257229XSmall and building a Pomodoro timer.  We are (at lest for now) doing this using Test Driven Development. 

This immediately raised an interesting issue, which I think I’ve found a solution for but would be eager to hear how others deal with this issue.

Here’s the background.  We created a Task object, which so far looks like this (excerpt):

class Task
{
    public int ExpectedPomodoros { get; private set;  }
    public string Name { get; private set; }
    private Pomodoro _currentPomodoro;


    public Task( string name,  int expectedPomodoros )
    {
        _currentPomodoro = 
              new Pomodoro( TimeSpan.FromMinutes( 20 ) ) ;
        Name = name;
        ExpectedPomodoros = expectedPomodoros;
    }

We can of course have tests for whether the ExpectedPomodoros is greater than or equal to 1, and whether the name is valid, but two problems immediately arise:

  1. It is tedious to add a test for every member’s validity and
  2. What do we do about the private member variables such as _currentPomodoro?

Point #2 is that the test framework won’t have visibility into the private member, nor should it, but it would be a pretty big bug to have a null _currentPomodoro – exactly the kind of bug I’d like the Unit Tests to find.

My solution is to reach back 20 years to an old concept in object oriented programming called Invariants.  The idea was that each class had a set of invariant conditions that must be true at the start and end of every method (except only at the end of the constructor and, in C+++, only at the start of the destructor).  A class was not valid if its invariants were not valid.

Transposing this forward to today’s Silverlight Unit Tests, we get,

public bool Invariants
{
    get
    {
        return
        ! String.IsNullOrEmpty( Name ) &&
        ExpectedPomodoros >= 1 &&
        _currentPomodoro != null
    }
}

and we are now free to write a unit test to test the invariants:

 [TestMethod]
 public void NewTaskIsValid()
 {
     Task t1 = new Task("testTask", "a test", 2);
     Assert.IsTrue( t1.Invariants );
 }

One principle of Unit Testing in general and TDD in particular is that each test should test just one thing, and always give an unambiguous answer.  This approach violates both of these “rules” — if this test were to fail, and you were testing that 15 things are invariant, you have to figure out which thing was not invariant, and that might involve a bit of work.

My answer is to add only trivial items (e.g., Name is not null or empty) and to add them one by one so if they fail you know which (likely) failed.  Further, I don’t see a better way to test private variables. 

So, is this brilliant, or old-hat, or just wrong?

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Essentials, Patterns & Skills, TDD and tagged , . Bookmark the permalink.

13 Responses to Test Driven Development–Testing Private Values

Comments are closed.