Вкратце: код создает новый ServerSocket для прослушивания на определенном порту; и , когда «этот запрос» входит в этот порт, он запускает поток для обработки этого клиента.
Проблема с этим кодом:
- Он проходит некоторое время (истина) цикл; так что метод не должен когда-либо возвращаться
- И кроме того, это написано в трудно проверить путь; в основном потому, что у вас есть эти два вызова в
new
в этом методе.
Я объясню, как вы могли преодолеть вторую часть; а затем поговорим о первом пункте. Что касается самого «тестирования», у вас есть два варианта:
- Замок в PowerMock (уродливый); или, может быть, шпионы Мокито могли бы помочь; до mock Эти призывы к новому. (Mockito в порядке, но PowerMock не так много в моих глазах)
- Предпочтительно: изменить свой код, чтобы его было легко проверить; а затем использовать инъекцию зависимостей.
Как:
public class Server {
private final SocketFactory socketFactory;
private final ThreadFactory threadFactory;
public Server() {
this(new SocketFactory(), new ThreadFactory());
}
Server(SocketFactory socketFactory, ...
this.socketFactory = socketFactory...
public void startServer() throws IOException
{
ServerSocket ss = socketFactory.createSocketFor(portNum);
while(true)
{
Socket s = ss.accept();
Thread t = threadFactory.newThreadFor(new ConnectionHandler(s));
t.start();
}
}
А теперь ... все супер просто: вы можете использовать этот второй пакет защищен CTOR для вставки издевался заводов; а затем вы можете настроить/убедиться, что эти заводы видят ожидаемые вами вызовы.
Конечно, это может выглядеть как «более» работа; так как теперь вам нужно создать эти два других класса (и на самом деле вы можете использовать интерфейсы плюс impl классы).Но дело в том, что вы получаете лучший дизайн, который не только легче тестировать, но и проще поддерживать и улучшать.
И затем: создание потоков «голого металла» на самом деле не является хорошей практикой. (особенно не в режиме while-true, если вы все еще ищете свою ошибку). Вы должны изучить какой-то класс ThreadPool; чтобы быть уверенным, что вы не постоянно создает новый темы. Это «дорогие»; вы должны очень предпочесть «повторное использование» потоков. И есть библиотеки, которые помогают с этим!
OK, возвращаясь к другой проблеме: как сейчас, вы просто не может разумно блока теста этого метод из-за некоторое время (правда). Вы видите, когда вы mock, что ServerSocket, то вызов accept() не будет блокироваться; и вы столкнулись с каким-то бесконечным циклом, создавая насмешливые потоки.
Итак: вам нужно либо переработать этот код (чтобы его можно было остановить извне) ... или вы могли бы настроить макет ThreadFactory, чтобы вернуть mocked thread; что вызывает какое-то конкретное исключение. И тогда ваш модульный тест просто ожидает, что исключение будет выбрано - как косвенное «доказательство», что все, что вы ожидали, действительно имело место.
Цикл 'while (true)' трудно проверить, потому что тест никогда не закончится (если вы не сможете вызвать исключение, которое должно быть выбрано в течение while (true) -loop). ;-) –
На всякий случай вы чувствуете склонность принять мой ответ; было бы здорово, если бы вы могли подумать об этом завтра ... поскольку я уже нажимал ежедневную кепку на день ;-) – GhostCat