在Swift中,为了测试默认访问级别类,可以将@testable
放在测试类标题中,使内部访问级别类可以从测试包中访问和测试,而不需要公开类中的所有内容。我想知道Java是否有办法达到相同的目的?如何在不公开任何东西的情况下测试Java中的默认访问级别类?
如何从测试包中测试Java中的默认访问级别类而不将类中的所有内容都公开?
在Swift中,为了测试默认访问级别类,可以将@testable
放在测试类标题中,使内部访问级别类可以从测试包中访问和测试,而不需要公开类中的所有内容。我想知道Java是否有办法达到相同的目的?如何在不公开任何东西的情况下测试Java中的默认访问级别类?
如何从测试包中测试Java中的默认访问级别类而不将类中的所有内容都公开?
有在@VisibleForTesting注解一些java库,但通常它不会阻止非法访问。即使让包保护也不能解决所有问题,因为还有一些其他类可以使用测试代码,这可能会导致一些意外行为。我最近偶然发现了很好的结构,使您可以显示有关暴露出一些方法来测试
public class A{
private int someMethodYouWantToTest(){}
private Testability testability = new Testability();
class Testability{
int exposedMethodForTest(){
someMethodYouWantToTest()
}
}
}
然后在您的测试类
public class Test{
private A underTest = new A()
public void testHiddenMethod(){
a.testability.exposedMethodForTest()
}
}
这样你的私有方法是私有的意图,只能访问如果通过专门的可测试性内部类来清楚地说明它的用途,那么不会有人偶然在测试之外调用您的方法。这解决了可能从其他地方调用但实际上是私有的包保护业务方法的问题。
在Java中,您可以做的唯一的事情就是让产品受保护如果您希望在测试代码中使用它们(即:如果您不希望它们公开)。
例子:我的课经常看起来像
class Whatever
public Whatever() { this(new A(), new B()); };
Whatever(A a, B b) { ...
允许我使用需要依赖注入单元测试的第二个构造;同时依靠生产法规应该总是使用公共构造函数的“惯例”。
所以,即使当我有我不想在我的包外使用的类...我公开的构造函数表明:请使用这一个。
这个想法基本上是你的生产代码和测试代码驻留在相同名称的包中。
换句话说:Java没有这个好的特性,只允许访问来测试代码。
报价是回答了similar question
“
通常不需要单元测试私有方法直接。由于他们是 私人,认为它们的实现细节。没有人曾经打算 到打电话给其中的一个,并期望它能够以特定的方式工作
你应该改为测试你的公共接口如果 调用你的私有方法的方法是工作如你所期望的那样,你假设 扩展你的私有方法正常工作。“
这相当于选项1在这个link
如果1不适合你的目标,你可以尝试在链接中提到方法2,3和4
当然,如果测试本来是私有的,那么它就不是完美的,即使它只在类自己的包中。另一方面,无论如何推荐(并且有很多好处)不依赖于推理,而是依赖于接口。
这意味着:为客户端提供一个接口,该接口只声明您想公开的方法,并让您的实现中要测试的方法受保护,并且不要将其包含在接口中。