11

当我尝试对 JDialog 对象中的某些方法进行单元测试时,我收到了 NullPointerException。我必须初始化对话框父级的模拟版本以及将使用的另一个类(除了调用静态方法。代码如下:

@RunWith( PowerMockRunner.class )
@PrepareForTest( ControlFileUtilities.class )
public class StructCompDlgTest 
{
  @Before
  public void setUp() throws Exception
  {
    controlFrame    = org.mockito.Mockito.mock( ControlFrame.class );
    structCmpDlg    = new StructureCompareDialog( controlFrame );
    serverPipeline  = org.mockito.Mockito.mock( ServerPipeline.class );
  }
...
}

用于构建对话框的代码在这里:

StructureCompareDialog( IControlFrame controlFrame )
{
 super( (Frame) controlFrame, "title", true );
 ...
}

当调用超级构造函数时,我最终会在 java.awt.Window.addOwnerWindow(Window.java:2525) 处得到 NullPointerError"

void addOwnedWindow(WeakReference weakWindow) {
  if (weakWindow != null) {
    synchronized(ownedWindowList) {  ***<<------ offending line***
      // this if statement should really be an assert, but we don't
      // have asserts...
      if (!ownedWindowList.contains(weakWindow)) {
        ownedWindowList.addElement(weakWindow);
      }
    }
  }
}

我知道我正在将静态和摇摆 gui 混合在一个有毒的漩涡中,但我别无选择。我被指示将一些单元测试与现有代码组合在一起。我不知道出了什么问题。

谢谢

4

3 回答 3

5

看起来很棘手!本质上,您将不得不找到controlFrame作为构造函数的一部分被调用的所有方法,然后撒上一些调用

when(controlFrame.methodCalled()).thenReturn(somethingSensible);

如果这看起来像是一项艰巨的工作,那么尝试创建一个IControlFrame您在测试 setUp() 中创建的默认实现并使用模拟的替代品怎么样。

前段时间我有一个类似的问题,我试图对 Spring JMS 侦听器进行单元测试。无论对错,我通过创建自己的默认实现得到了一个可行的解决方案,DefaultMessageListenerContainer它给了我与你所描述的类似的问题。我的解决方案涉及使用我自己的测试特定版本扩展实际实现,看起来像这样

/**
 * Empty mocked class to allow unit testing with spring references to a
 * DefaultMessageListenerContainer. The functionality on this class should never be
 * called so just override and do nothing.  
 */
public class MockDefaultMessageListenerContainer extends DefaultMessageListenerContainer {

    public MockDefaultMessageListenerContainer() {
    }

    public void afterPropertiesSet() {
    }

    @Override
    protected Connection createConnection() throws JMSException {
        return null;
    }
}

在我的示例中,我能够通过传回有null问题的 createConnection() 方法的值来运行我的测试。也许同样的方法可以帮助你。

于 2012-07-03T14:53:29.623 回答
0

ownedWIndowList是在课堂上transientjava.awt.Window您的实例是否JDialog被序列化?如果是这样,您可能需要使用readObject(java.io.ObjectStream)Serializable 接口中的方法重新初始化ownedWIndowList

于 2017-02-22T22:39:09.350 回答
0

我不知道您的 IControlFrame 是什么样的,但是将模拟传递Frame给 super() 不起作用。我必须实例化我自己的版本:

private class EmptyControlFrame extends JFrame implements IControlFrame {

    @Override
    public JFrame getFrame() {
        return null;
    }

    // return null for any other overrides from IControlFrame
}

然后在你的 setUp() 中:

controlFrame = new EmptyControlFrame();
于 2017-03-27T22:51:15.033 回答