注释使私有方法只对测试类公开

谁有办法解决这个共同的需求。

我的申请里有一门课。

有些方法是公共的,因为它们是 API 的一部分, 还有一些是私有的,因为它们用于内部使用,使内部流程更具可读性

现在,假设我想编写一个单元测试,或者更像是一个集成测试,它将位于一个不同的包中,这个包允许调用这个方法,但是,如果你试图从应用程序本身的类中调用这个方法,那么对这个方法的普通调用是不允许的

所以,我在考虑类似的事情

public class MyClass {


public void somePublicMethod() {
....
}


@PublicForTests
private void somePrivateMethod() {
....
}
}

上面的注释将私有方法标记为“ public for test” which means, that compilation and runtime will be allowed for any class which is under the test... package , while compilation and\or runtime will fail for any class which is not under the test package.

有什么想法吗? 有这样的注释吗? 还有更好的办法吗?

似乎您编写的单元测试越多,打破封装的强制性就越多... ..。

185767 次浏览

关于 测试私人方法的一篇文章展示了一些测试私有代码的方法。使用反射会给程序员带来额外的负担,如果重构完成了,字符串不会自动更改,但我认为这是最干净的方法。

我不知道任何这样的注释,但以下可能是有价值的: unit testing private methods
或者如下: < a href = “ https://stackoverflow. com/questions/2020254/java-unit-test-place-a-private-method-under-test”> JMockit

通常的方法是将私有方法设置为 protected 或 package-private,并将此方法的单元测试放在与被测类相同的包中。

Guava has a @VisibleForTesting annotation, but it's only for documentation purposes.

考虑使用接口公开 API 方法,使用工厂或 DI 发布对象,以便使用者只通过接口了解它们。接口描述了发布的 API。这样,您就可以在实现对象上公开任何您想要的东西,而实现对象的使用者只能看到通过接口公开的那些方法。

您不能这样做,因为从那时起,您甚至无法编译您的测试?编译器不会考虑注释。

对此有两种通用的方法

第一种方法是使用反射来访问这些方法

第二种方法是使用 package-private 而不是 private,然后将测试放在同一个包中(但是放在不同的模块中)。它们基本上对其他代码是私有的,但您的测试仍然能够访问它们。

当然,如果你有黑盒测试,你也不应该访问私人会员。

If your test coverage is good on all the public method inside the tested class, the privates methods called by the public one will be automatically tested since you will assert all the possible case.

JUnit Doc 表示:

测试私有方法可能意味着应该将这些方法移动到另一个类中以提高可重用性。 但如果你一定要..。 如果使用的是 JDK 1.3或更高版本,则可以借助 PrivilegedAccessor 使用反射颠覆访问控制机制。有关如何使用它的详细信息,请参阅 读这篇文章。

Or you can extract this method to some 策略 object. In this case you can easily test extracted class and don't make method public or some magic with reflection/bytecode.

据我所知,没有这样的注释。最好的方法是像其他一些建议那样使用反射。看看这个帖子:
如何测试具有私有方法、字段或内部类的类

您应该只注意测试该方法的异常结果。例如: 如果您期望一个 IllegalArgumentException,但是您将得到“ null”(Class: java.lang.response。InvocationTargetException).
我的一个同事建议在这些情况下使用
Powermock 框架,但我还没有测试它,所以不知道它到底能做什么。尽管我已经使用了 Mockito 框架,它也是一个很好的框架(但我认为它不能解决私有方法异常问题)。

尽管拥有@PublicForTest 注释是一个很好的主意。

干杯!

Dp4j 有你需要的。本质上,您所要做的就是将 dp4j 添加到您的类路径中,并且每当用@Test (JUnit 的注释)注释的方法调用一个私有的方法时,它就会工作(dp4j 将在编译时注入所需的反射)。您还可以使用 dp4j 的@TestPrivates 注释来更加明确。

If you insist on also annotating your private methods you may use Google's @VisibleForTesting annotation.

我只是把测试放在类里面,把它变成一个内部类: Https://rogerkeays.com/how-to-unit-test-private-methods

我们最近发布了一个库,它可以通过反射很好地访问私有字段、方法和内部类: 边界盒

对于像

public class Outer {
private static class Inner {
private int foo() {return 2;}
}
}

它提供的语法类似于:

Outer outer = new Outer();
Object inner = BoundBoxOfOuter.boundBox_new_Inner();
new BoundBoxOfOuter.BoundBoxOfInner(inner).foo();

您必须做的唯一一件事情来创建的边界框类是写 @BoundBox(boundClass=Outer.class)BoundBoxOfOuter类将立即生成。

好的,这里有两样东西混合在一起。首先,当您需要标记一些仅在测试中使用的内容时(我同意@JB Nizet 的观点) ,使用番石榴注释会比较好。

另一件不同的事情是测试私有方法。为什么要从外部测试私有方法?我是说。.您应该能够通过它们的公共方法测试对象,并且在最后测试它的行为。至少,我们正在做的和试图教给初级开发人员的总是试图测试私有方法(作为一个好的实践)。