maa*_*nus 7 java testing reflection private
关于私有方法测试的意义有不同的意见,例如,这里和这里.我个人认为这是有道理的,问题是如何正确地做到这一点.在C++中你可以使用#definehack或者使用测试类friend,在C#中有InternalsVisibleToAttribute,但是在Java中我们必须使用反射或使它们"可见以进行测试"并对其进行注释以使意图清晰.两者的缺点应该非常清楚.
我认为应该有更好的东西.从...开始
public class Something {
private int internalSecret() {
return 43;
}
}
Run Code Online (Sandbox Code Playgroud)
能够在测试代码中调用私有方法会很好
@MakeVisibleForTesting Something something = new Something();
Assert.assertEquals(43, something.internalSecret());
Run Code Online (Sandbox Code Playgroud)
这里的注释会静默地将所有调用转换为something使用反射的私有方法.我想知道龙目岛是否可以做到(并会问作者).
做这么多魔术很可能证明太复杂了,无论如何它都需要一些时间,所以我正在寻找一些替代方案.也许用类似的东西@Decapsulate来注释正在测试的类,并使用注释处理器来生成Decapsulated_Something类似的类
public class Decapsulated_Something {
public Decapsulated_Something(Something delegate) {
this.delegate = delegate
}
public boolean internalSecret() {
// call "delegate.internalSecret()" using reflection
}
...
}
Run Code Online (Sandbox Code Playgroud)
这将允许使用
Decapsulated_Something something = new Decapsulated_Something(new Something());
Assert.assertEquals(43, something.internalSecret());
Run Code Online (Sandbox Code Playgroud)
我对注释处理没有多少经验,所以我先问一下:
执行此实现似乎很麻烦.它可能不值得.而只是使方法包默认.
但是,如果您决定调用私有方法,则可以在类中使用setAccessibleDecapsulated_something以允许通过反射进行调用.所以这很简单.
如果能够在测试代码中调用私有方法就好了,比如
Run Code Online (Sandbox Code Playgroud)@MakeVisibleForTesting Something something = new Something(); Assert.assertEquals(43, something.internalSecret());
有一个方法注释之类的东西,查看dp4j的@TestPrivates:
@Test
@TestPrivates
//since the method is annotated with JUnit's @Test this annotation is redundant.
// You just need to have dp4j on the classpath.
public void somethingTest(){
Something something = new Something();
int sthSecret = something.internalSecret();
Assert.assertEquals(43, sthSecret); //cannot use something.internalSecret() directly because of bug [dp4j-13][2]
}
Run Code Online (Sandbox Code Playgroud)