javaconstructortestabilityconstructor-injection

Testable Java Code: using model beans with a constructor


According to Misko Hevery that has a testability blog. Developers should avoid 'holder', 'context', and 'kitchen sink' objects (these take all sorts of other objects and are a grab bag of collaborators). Pass in the specific object you need as a parameter, instead of a holder of that object.

In the example blow, is this code smell? Should I pass only the parameters that are needed or a model/bean with the data that I need.

For example, would you do anything like this: Note. I probably could have passed the data as constructor args. Is this a code smell?

public Parser {
  private final SourceCodeBean source;

  public Parser(final SourceCodeBean s) {
    this.source = s;
  }

  public void parse() {
     // Only access the source field
     this.source.getFilename();
     ...
     ... assume that the classes uses fields from this.source
     ...
  }

}

public SourceCodeBean {
   private String filename;
   private String developer;
   private String lines;
   private String format;

   ...
   ...
   <ONLY SETTERS AND GETTERS>
   ...
}

...

Or 

public Parser {


  public Parser(String filename, String developer, String lines ...) {
    ...
  }

}

And building a test case

public void test() {
  SourceCodeBean bean = new SourceCodeBean():
  bean.setFilename();

  new Parser().parse();
}

Another question: With writing testable code, do you tend to write TOO many classes. Is it wrong to have too many classes or one class with too many methods. The classes are useful and have a single purpose. But, I could see where they could be refactored into one larger class...but that class would have multiple purposes.


Solution

  • You will also notice that Misko Hevery advises to group parameters in classes, whenever the parameter count increases or in cases where this is logically acceptable.

    So in your case, you can pass the SourceCodeBean without remorse.