Powermock, Mockito nullpointerexception при вызове super() JDialog
Я получаю исключение NullPointerException при попытке unit test некоторых методов в объекте JDialog. Я должен инициализировать макетную версию родителя диалога, а также другой класс, который будет использоваться (в дополнение к вызову статического метода. Код выглядит следующим образом:
@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 );
...
}
когда вызывается суперструктор, я в конечном итоге получаю NullPointerError в java.awt.Window.addOwnerWindow(Window.java:2525) "
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);
}
}
}
}
Я знаю, что смешиваю статику и свинг-ги в ядовитом вихре, но у меня нет выбора. Мне была дана инструкция, чтобы собрать некоторые модульные тесты с существующим кодом. Я понятия не имею, что происходит не так.
Спасибо
Ответы
Ответ 1
Выглядит сложно! По существу вам придется найти все методы, вызываемые в controlFrame
как часть конструктора, а затем посыпать некоторые вызовы
when(controlFrame.methodCalled()).thenReturn(somethingSensible);
Если это выглядит сложной задачей, как насчет того, чтобы создать стандартную реализацию IControlFrame
, которую вы создаете как часть вашего тестового setUp(), и использовать эту установку макета.
У меня была аналогичная проблема некоторое время назад, когда я пытался прослушивать unit test a 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(). Возможно, тот же подход может помочь вам.
Ответ 2
ownedWIndowList
transient
в классе java.awt.Window
. Является ли ваш экземпляр JDialog
сериализованным? Если это так, вам может понадобиться использовать метод readObject(java.io.ObjectStream)
из интерфейса Serializable для повторной инициализации ownedWIndowList
Ответ 3
Я не знаю, как выглядит ваш IControlFrame, но передача mocked 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();