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

时间:2015-03-02 20:18:34

标签: java android unit-testing junit mockito

在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()是否使用相应的loadItems()进行调用id(使用Mockito之类的东西)。这不是一个好方法"虽然测试私有方法。

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

2 个答案:

答案 0 :(得分:4)

你嘲笑"这样做会让我成为一个糟糕的软件开发人员吗?"

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

我个人反对测试私有方法。在我看来,单元测试应该在可见方法而不是私有方法上进行。测试私有方法有点破坏封装点,使方法更加明显,而不仅仅是为了单元测试,我觉得不对。

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

更好的(这是我建议的)是移动

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

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

答案 1 :(得分:1)

恕我直言,如果能让代码更好,更容易维护,那么最好是进行测试,我觉得这是一个好主意。

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

我还要补充说,该方法是无效的,因此我认为比仅仅断言返回值更难以测试副作用。

或许考虑像

这样的东西

列出loadItems(int page)

然后检查返回的列表。