为什么Java使包访问失效?

时间:2013-12-02 14:49:01

标签: java unit-testing encapsulation access-modifiers testability

我问的是这个问题,因为我认为他们这样做的原因非常充分,而且大多数人都没有正确使用它,而且从目前为止我的行业经验来看也是如此。但如果我的理论是正确的那么我不确定他们为什么包含私人访问修饰符......?

我相信如果正确使用默认访问,它可以提供增强的可测试性,同时保持封装。它还会使私有访问修饰符变得多余。

默认访问修饰符可用于通过对需要从世界其他地方隐藏的方法使用唯一包来提供相同的效果,并且它在不影响可测试性的情况下执行此操作,如测试文件夹中的包,同样能够访问源文件夹中声明的所有默认方法。

我相信这就是为什么Java使用包访问作为'默认'。但我不确定为什么他们也包括私人访问,我确信有一个有效的用例......

2 个答案:

答案 0 :(得分:2)

我同意将默认(包私有)修饰符用于测试要访问的内容,但我不同意私有是不必要的。即使是测试,也有许多不需要看到的东西。

对于一个好的测试,实现细节是不必要的,不应该在课外看到。测试越“白盒”,它就越脆弱。我通常将默认修饰符限制为我希望通过依赖注入设置的字段,并在测试中手动设置。 (我也可以使用构造函数注入并摆脱它,但这更方便。)

答案 1 :(得分:0)

我提出很少的思考实验。请考虑以下代码:

public void promoteUser(User user)
{
    int newRank = computeNew(user);
    user.setRank(newRank);
}

private int computeNewRank(User user)
{
    return user.getRank() + 1;
}

有人可能觉得应该测试computeNewRank(真正的实现可能会做更多的事情)。但是让我们暂时忘记这一点并通过内联的魔力来做到这一点:

public void promoteUser(User user)
{
    int newRank = user.getRank() + 1;
    user.setRank(newRank);
}

这个实验的美妙之处在于它适用于任何大小的私人方法。您总是可以想象自己内联私人成员并问自己“我真的想在这里测试什么?”。它是私有方法本身,还是新的类/组件,具有伪装成私有方法的全新功能?关键是,你应该很少(如果有的话!)需要测试私有(甚至包/内部)成员。对于外界而言,对于合同消费者来说,这些都是无关紧要的细节。

现在,我们当然可以用系统测试替换所有内容。但那你的常规工作流程会是什么样子?如果为了测试等级促销代码你必须登录用户,注册会话,等待3分钟,输入促销代码,接收短信,确认...你看到了我的观点。

值得记住的是,单元测试适合您,而不是相反。您可以弯曲它们,调整它们,使它们适合,以便您可以提供更好质量的软件。他们的目的不是来帮助您实现 100%覆盖的神奇目标,而是为您提供有关您正在做的事情的即时反馈,以便您能够更快地做出反应错误和失败你将遇到。或者换句话说,提高您的工作效率