我对Java的座右铭是"仅仅因为Java有静态块,它并不意味着你应该使用它们." 除了笑话之外,Java中有很多技巧会让测试成为一场噩梦.我最讨厌的两个是匿名类和静态块.我们有很多使用静态块的遗留代码,这些是我们编写单元测试的烦恼之一.我们的目标是能够为依赖于此静态初始化的类编写单元测试,并且代码更改最少.
到目前为止,我对同事的建议是将静态块的主体移动到私有静态方法中并调用它staticInit
.然后可以从静态块内调用此方法.对于单元测试,依赖于此类的另一个类可以轻松地staticInit
使用JMockit进行模拟而不执行任何操作.我们在示例中看到这一点.
public class ClassWithStaticInit {
static {
System.out.println("static initializer.");
}
}
Run Code Online (Sandbox Code Playgroud)
将改为
public class ClassWithStaticInit {
static {
staticInit();
}
private static void staticInit() {
System.out.println("static initialized.");
}
}
Run Code Online (Sandbox Code Playgroud)
这样我们就可以在JUnit中执行以下操作.
public class DependentClassTest {
public static class MockClassWithStaticInit {
public static void staticInit() {
}
}
@BeforeClass
public static void setUpBeforeClass() {
Mockit.redefineMethods(ClassWithStaticInit.class, MockClassWithStaticInit.class);
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这种解决方案也有其自身的问题.您无法在同一个JVM上运行DependentClassTest
,ClassWithStaticInitTest
因为您实际上希望运行静态块ClassWithStaticInitTest
.
你完成这项任务的方式是什么?或者你认为哪种更好,非基于JMockit的解决方案更干净?
我为JLabels和AbstractButtons编写了一个MnemonicsBuilder类.我想编写一个方便的方法setMnemonics( JFrame f )
,它将迭代JFrame的每个子节点并选择JLabel和AbstractButtons.如何获取对JFrame中包含的所有内容的访问权限?我试过了:
LinkedList<JLabel> harvestJLabels( Container c, LinkedList<JLabel> l ) {
Component[] components = c.getComponents();
for( Component com : components )
{
if( com instanceof JLabel )
{
l.add( (JLabel) com );
} else if( com instanceof Container )
{
l.addAll( harvestJLabels( (Container) com, l ) );
}
}
return l;
}
Run Code Online (Sandbox Code Playgroud)
在某些情况下,这很好用.在其他情况下,它耗尽内存.我没想到什么?有没有更好的方法来搜索子组件?我的递归有缺陷吗?这不是Swing中"包含"其他东西的图片 - 例如,Swing不是Root Tree吗?
JFrame
|
|\__JMenuBar
| |
| \__JMenu
| |
| \__JMenuItem
|
|\__JPanel
| |
| |\__JButton
| |
| |\__JLabel …
Run Code Online (Sandbox Code Playgroud)