Can you take the single responsibility principle too far?

This morning, I had a conversation with a colleague of mine who has recently started using EDD about "exposing things just for the purpose of testing." Although I have run across the odd occasion where I may need to add a get property to a class in order to verify a value, usually I find this means that the class is doing too much.

Here's the scenario:

Imagine a command-line application that needs to perform several actions. Each action is responsible for parsing and validating the parameters for itself. One possible structure looks like this:

 public class PourWaterAction : IAction 
{
  PourWaterAction(string[] args)
  {
  }
 
  public bool ValidateParamters() 
  {
     // throws if invalid 
  } 

  public void Perform() 
  { 
    // do real stuff here 
  }
}

Now we've got tests that will assert if ValidateParameters throws, but how do we write a test that determines if the parameters are properly parsed when ValidateParameters doesn't throw?

This is where the interesting conversation starts: my feeling was that the PourWaterAction class shouldn't be doing two things, and validation should be delegated to a different class. Perhaps something like this:

 public static class PourWaterActionValidator
{
  public static PourWaterData Validate()  
  {
    // Either throw or return a populated structure
  }
}

or

 public class PourWaterActionValidator : IActionValidator
{
  public PourWaterData Validate()  
  {
    // Either throw or return a populated structure
  }
}

Now we can move the validation tests to the new class, and easily write a test for passing conditions as well as failing ones. Straightforward enough, right?

Possibly not. My colleague was of the opinion that: 

  • This was creating extra classes unnecessarily which, when taken to the extreme, would mean tons of different files in the project.
  • Even if another class was created, it should be visible only to PourWaterAction which means it wouldn't be possible to test either.

This means that the only way to test it was to add get properties to PourWaterAction so the tests could verify that the parsing had been performed correctly — "adding things just for the sake of testing"

So, what would you do in this situation? And do you believe that classes should always strive to do one thing and one thing only?