【问题标题】:Is it bad practice to make a method package or private for the sake of testing?为了测试而制作方法包或私有方法是不好的做法吗?
【发布时间】:2015-03-02 20:18:34
【问题描述】:

在 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 个公共方法绝对应该进行测试。令人担忧的是,refresh()init() 方法几乎相同,只是减去了一些处理 id 的逻辑。

似乎最简单的方法是为loadItems() 编写单元测试,然后验证init()refresh() 是否使用适当的ID 调用loadItems()(使用类似Mockito 的东西)。不过,测试私有方法并没有“好方法”。

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

【问题讨论】:

  • 也许您当前的课程违反了Single Responsibility Principle?例如,您可以创建一个可以测试的专用ItemsLoader 类,并将此类的(模拟)实例注入当前类。更准确地说,我错过了一些上下文。
  • 嗯...我想后续问题可能是“什么时候创建一个新的类矫枉过正?”这显然有点模糊。你和@kha 本质上是在推荐同样的东西。
  • +1。也许(我不确定)如果你能把它变成一个正确的问题,它可能适合 [Programmers SE](programmers.stackexchange.com)。不过不要忘记先试用搜索功能:)
  • @loeschg 这是我工作过的公司的一个矛盾点。有人说如果要测试的方法是私有的,那么它们不应该在这个类中。有些人只是使用了一个允许测试私有方法的测试框架。但是改变可见性水平是相当糟糕的——这种方法从未被设计成突然出现在公共合同中。程序员的普遍共识是你不测试私有方法。
  • 当您想测试私有方法时,首先要问自己的是为什么它是私有的?。你有 99% 的机会回答因为应该在其他班级。因此,对其进行保护、测试、重构以将其提取到一个新类中并在原始类中创建一个私有协作者。

标签: java android unit-testing junit mockito


【解决方案1】:

你问“这样做会让我成为一个糟糕的软件开发人员吗?”

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

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

如果我是你,我会测试我的两个公共方法。今天,您的两种方法几乎相同,通过使其包可见来测试您的私有方法更容易。然而,明天可能就不再是这样了。由于这两种方法都是公开的,并且其他类可以轻松访问,因此如果发生这种情况并且这两种方法分开了,您可能正在测试错误的东西。

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

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

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

【讨论】:

    【解决方案2】:

    恕我直言,测试总比不测试好,如果它使代码更好且更易于维护,我认为这是个好主意。

    我也同意 Niek 将逻辑放在另一个类中。

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

    也许考虑一下

    列出加载项(int page)

    然后检查返回的列表。

    【讨论】:

      猜你喜欢
      • 2023-03-04
      • 1970-01-01
      • 2012-03-01
      • 2021-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      相关资源
      最近更新 更多