当调用super()JDialog时,Powermock,Mockito nullpointerexception

时间:2012-06-27 19:15:42

标签: swing junit nullpointerexception mockito powermock

当我尝试对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,但我别无选择。我得到了将现有代码与单元测试结合在一起的指令。我不知道出了什么问题。

由于

3 个答案:

答案 0 :(得分:5)

看起来很棘手!基本上你必须找到controlFrame作为构造函数的一部分调用的所有方法,然后将一些调用转移到

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

如果这看起来像是一件困难的事,那么如何尝试创建一个IControlFrame的默认实现,您可以将其作为测试setUp()的一部分创建并使用该模拟的instea。

前一段时间我遇到过类似的问题,我试图对一个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;
    }
}

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

答案 1 :(得分:0)

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

答案 2 :(得分: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();