是否可以更改 class 接口以提高可测试性

Is it ok to change the class interface to improve testability

我目前正在与一位同事讨论,他建议我 分离出我 class 中使用的一个组件 创建一个abstract interface 并从外部设置该组件的具体实例。我可以用它来 在单元测试中创建一个模拟 ,从而提高 class 的可测试性。

虽然我很理解这个论点,但我觉得我的class的design/interface受此影响。

对我来说,这归结为一个问题:为了可测试性而更改 class 接口是否可以?接口和可测试性哪个更重要?

这样笼统的提问可以吗,还是举个例子?

非常感谢。

如果您想要使用模拟而不是真实的 class,那么您已经在设计两种可互换的实现:真实实现和测试替身。这就是提取接口的充分理由。

可测试性很重要;实用的可测试单元比“纯”不可测试单元有用得多。

虽然您可以使用像 setFooForTest 这样的名称来标记以测试为中心的方法,或者使用像 @VisibleForTesting 这样的测试文档注释,但理想情况下,您应该反映出测试是您的接口的使用者,并且您的接口应该对您的消费者和您的测试来说足够通用。这可能意味着使用依赖注入或方法重载,如下所示:

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

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