Home > Back-end >  Is it ok to change the class interface to improve testability
Is it ok to change the class interface to improve testability

Time:10-13

I am currently in a discussion with a colleague who suggests that I separate out a component that is used in my class, create an abstract interface and set the concrete instance of that component from the outside. I could use this to create a mock in the unit test so that the testability of the class is improved.

Although I understand the argument very well, I feel that the design/interface of my class is negatively affected by this.

For me, this boils down to the question: is it okay to change the class interface for the sake of testability? What is more important, the interface or the testability?

Is it okay to ask the question in such a general way, or should I present an example?

Thank you very much.

CodePudding user response:

If you are tempted to use a mock instead of the real class, then you are already designing for two interchangeable implementations: The real implementation and the test double. That's reason enough to extract out an interface.

Testability is important; a pragmatic testable unit is much more useful than a "pure" untestable unit.

Though you can label test-focused methods using names like setFooForTest or use test documentation annotations like @VisibleForTesting, ideally you should reflect that the test is a consumer of your interface and that your interface should be general enough for your consumer and your test. That might mean employing dependency injection or method overloads, like this:

public int doThing() {
  return doThing(new DefaultCollaborator());
}

/** Does thing with a particular collaborator. Useful for testing. */
/* package */ int doThing(Collaborator collaborator) {
  // ...
}
  • Related