为了测试而将方法包或私有化是不好的做法吗?

Is it bad practice to make a method package or private for the sake of testing?

在 Java 中(在 Android 特定上下文中,但这应该全面适用),删除 private 修饰符是否被认为是不好的做法 - 因此 package 具体 - 为了单元测试?

假设我有如下内容:

public void init(long id) {
    mId = id;
    loadItems(1);
}

public void refresh() {
    loadItems(mId);
}

private void loadItems(int page) {
    // ... do stuff
}

在这种情况下,我有 2 个 public 方法绝对应该测试。值得关注的是 refresh()init() 方法几乎完全相同,除了一些处理 id 的逻辑。

似乎最简单的方法是为 loadItems() 编写单元测试,然后只需验证 init()refresh() 都以适当的方式调用 loadItems() id(使用类似 Mockito 的东西)。虽然没有 "good way" 来测试私有方法。

这样做会让我成为一个糟糕的软件开发人员吗?我知道从技术上讲,私有方法不需要单元测试,但这将是一种简单的测试方法,IMO,尤其是在 loadItems() 有点复杂的情况下。

恕我直言,有测试总比没有好,如果它能让代码更好更容易维护,我认为这是个好主意。

我也同意上面的 Niek 将逻辑放在另一个 class。

我还要补充一点,该方法是无效的,因此有副作用,我认为这些副作用比简单断言返回值更难测试。

也许可以考虑

列出加载项(整页)

然后检查返回的列表。

你问了"Would doing that make me a bad software developer?"

我不认为这会让你成为一个糟糕的开发者。例如,如果您查看 .NET,它们甚至有一种方法允许其他库查看另一个库的内部结构以进行单元测试 (InternalsVisibleTo)。

虽然我个人反对测试私有方法。在我看来,单元测试应该在可见方法而不是私有方法上进行。测试私有方法在某种程度上破坏了封装的意义,并且仅仅为了单元测试而使方法比需要的更可见在我看来是错误的。

如果我是你,我会测试我的两种 public 方法。今天,您的两个方法几乎完全相同,并且通过使其包可见来更容易地测试您的私有方法。然而明天,情况可能不再如此。由于这两种方法都是 public 并且其他 classes 很容易访问,因此如果发生这种情况并且两者渐行渐远,您可能正在测试错误的东西。

更好的是(这是我推荐的)移动

private void loadItems(int page) {
    // ... do stuff
}

使用自己的接口 class ,然后使用单独的单元测试测试 loadItems(int page) 一次,然后通过确保它们调用接口来测试两个 public 方法与您期望的参数。这样,您就可以测试整个代码并避免我上面解释的陷阱。