【问题标题】:Powermock, Mockito nullpointerexception when calling super() JDialogPowermock, Mockito nullpointerexception 调用 super() JDialog 时
【发布时间】:2012-06-27 19:15:41
【问题描述】:

当我尝试对 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 混合在一个有毒的漩涡中,但我别无选择。我被指示将一些单元测试与现有代码组合在一起。我不知道出了什么问题。

谢谢

【问题讨论】:

  • 你有没有得到这个工作?如果是这样,您介意发布解决方案吗?
  • Starnge 你在synchronized(ownedWindowList) 得到空指针。如果您检查 Window.java 中的 ownedWindowList 数据成员,它已经被实例化并且再也没有分配给 null。想知道什么可能使这个数据成员为空。如果此数据成员被访问(使用反射)并且已更改为 null,您能否签入您的代码。最不可能的情况是需要手动更改此数据成员,但最好确保。
  • @glenneroo,我认为在这里放赏金而不是用自己的代码创建新问题是一个错误。您能否提供一些详细信息,例如您所做的事情以及您获得的异常堆栈跟踪。
  • @SergGr,您可能是对的,我的配置稍有不同(没有 PowerMockRunner),但异常和位置相同。堆栈跟踪似乎不是很有帮助,但我会创建另一个问题并希望它不会被标记为重复。
  • @glenneroo,实际上添加指向此问题的链接并提及您仍然没有解决问题的方法可能很有用。

标签: swing junit nullpointerexception mockito powermock


【解决方案1】:

看起来很棘手!本质上,您将必须找到所有在 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;
    }
}

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      我不知道您的 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();
      

      【讨论】:

        猜你喜欢
        • 2015-12-12
        • 2015-11-04
        • 1970-01-01
        • 1970-01-01
        • 2011-08-27
        • 1970-01-01
        • 1970-01-01
        • 2019-05-31
        • 1970-01-01
        相关资源
        最近更新 更多