Обработка событий Swing в тесте JUnit

У меня есть Java-приложение Swing с сетевым взаимодействием с несколькими «игроками», которые представлены как объекты-игроки, каждый со своим собственным потоком связи. В приложении есть объект «Команда», управляющий всеми объектами игроков. Несколько компонентов пользовательского интерфейса прослушивают события, передаваемые игроками через объект Team.

В моем проекте командный объект запускает все события в потоке Swing с помощью invokeLater, так что остальной части моего приложения не нужно беспокоиться о проблемах с потоками. Однако я не знаю, как протестировать класс Team в тесте JUnit.

Еще немного предыстории. Сначала у меня был объект Team, запускающий свои события в потоках объекта игрока (никакого переключения потоков). Модульный тест Team прошел успешно, но у меня возникло множество проблем с потоками в моем пользовательском интерфейсе с помощью invokeLaters и повсеместной синхронизации. Затем я решил упростить модель потоков, включив события запуска объекта Team в потоке Swing, но теперь модульный тест Team завершается ошибкой, потому что он не получает события. Что делать?

На ум приходит решение ввести дополнительный объект поверх Team, который выполняет переключение потоков и сохраняет исходный модульный тест нетронутым, но мне не нравится идея добавления сложности в производственный код только для того, чтобы модульный тест прошел успешно.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
3 021
3

Ответы 3

Возможно, вы можете использовать easymock, чтобы изолировать классы, которые вы хотите протестировать, и заставить макетные объекты получать события и проверять, что они запускаются.

Я бы порекомендовал EasyMock: http://www.easymock.org/

Из вашего рассказа кажется, что ваши юнит-тесты - это больше интеграционные тесты, и они очень сложные. Если это так, попробуйте упростить и изолировать. Вы, наверное, читали http://junit.sourceforge.net/doc/testinfected/testing.htm

Надеюсь, это поможет.

Вы правы, что я тестирую не один класс. Что я пытаюсь достичь, так это убедиться, что взаимодействие между несколькими процессами работает на уровне команды. Это взаимодействие между объектом, который я хочу протестировать, и мне нужно подумать, чтобы найти другой способ. Спасибо за совет.

Emile 01.12.2008 11:37

Когда я провел тестирование JUnit с EventQueue.invokeLater, я отделился от этой злой статики. Создать интерфейс с invokeLater можно методами isDispatchThread. Для производства реализация должна просто перенаправить на EventQueue. Для тестирования используйте свой собственный поток (который можно настраивать и отключать для каждого теста).

Еще один случайный совет:

  • Сделайте графический интерфейс как можно более тонким.
  • Продолжайте выводить потоки из всего остального, а все остальное из потоков.
  • С подозрением относитесь ко всему, что претендует на безопасность потоков.

Мне нравится твой совет, особенно второй. Ваше предложение ввести интерфейс, вероятно, будет правильным решением. Тем не менее, мне немного неудобно, что мне приходится делать это «просто», чтобы что-то проверить.

Emile 01.12.2008 11:46

A solution that comes to mind is to introduce an extra object on top of Team that does the thread switch and keep the original unit test intact, but I do not like the idea of introducing complexity in production code just to make a unit test succeed.

Я не знаю, так ли это здесь, но я часто обнаруживаю, что добавляемая мною «сложность» на самом деле является более высоким уровнем абстракции, улучшающим код.

Первоначальная идея имитирующих объектов заключалась не в том, чтобы упростить модульное тестирование, а в «обнаружении интерфейсов», чтобы создавать интерфейсы, которые представляют абстракции на вашем вездесущем языке, а не работать на уровне API.

Я согласен со сложностью и функциональной абстракцией, но в данном случае я имею дело «только» с проблемами потоковой передачи, которые можно довольно легко решить, выполнив большинство действий в потоке пользовательского интерфейса, за исключением того, что это усложняет тестирование. Спасибо, что заставили меня переосмыслить мои абстракции!

Emile 01.12.2008 11:44

Другие вопросы по теме