Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
3 / 3 / 2
Регистрация: 31.07.2017
Сообщений: 29
1

Как правильно тестировать в JUNIT

27.11.2017, 12:25. Показов 1132. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет!

Написал сетевой чат, теперь стоит задача сделать к нему юнит тесты. Насколько я понял, юнит тесты должны затрагивать только тестируемую логику и подтягивать как можно меньше зависимостей. Например, у меня есть класс Client, который логинится к серверу и соответственно шлет и принимает от него сообщения. Для общения с сервером выделен отдельный класс ConnectionToServer, реализующий транспортный уровень. Так вот, когда я тестирую методы класса Client, то работу ConnectionToServer я эмулирую. Т.е делаю класс наследник, который не ведет прямое общение с сервером, а просто как-то обрабатывает отсылку и прием сообщений, чтобы это было понятно для логики Client. А если я хочу протестировать класс ConnectionToServer, то мне необходимо уже создавать реальный экземпляр сервера и с ним работать или точно также вводить какую-то симуляцию?

Извиняйте за сумбур, раньше тесты не делал. Пока немного каша с Mock и Stub в голове.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.11.2017, 12:25
Ответы с готовыми решениями:

Junit тесты: как правильно реализовать проверку метода findAll?
Доброго времени суток, форумчане. Подскажите пожалуйста, как правильно реализовать проверку метода...

Как тестировать xpages?
Товарищи, а как у вас организован процесс тестирования xpages под разными пользователями? Как...

Как тестировать втаких условиях
Самописный прокси вставляет в хтмл скрипт для выполнения на странице, все работает, кроме...

Разработать класс-контейнер. Как тестировать?
задали курсовую работу. (ниже файл) но я не могу понять что нужно сделать? к какому результату...

7
614 / 488 / 175
Регистрация: 02.03.2010
Сообщений: 1,238
27.11.2017, 12:38 2
Mock'и для того и сделаны, что бы не делать
Цитата Сообщение от evggen0904 Посмотреть сообщение
Т.е делаю класс наследник, который не ведет прямое общение с сервером
Делаешь Mock ConnectionToServer'а при тестировании Client'а, и для всех методов, которые использует Client, "замокиваешь" поведение.
Цитата Сообщение от evggen0904 Посмотреть сообщение
А если я хочу протестировать класс ConnectionToServer, то мне необходимо уже создавать реальный экземпляр сервера и с ним работать или точно также вводить какую-то симуляцию?
Точно так же мокаешь, все что используется при тестировании.
1
3 / 3 / 2
Регистрация: 31.07.2017
Сообщений: 29
27.11.2017, 15:11  [ТС] 3
Пытаюсь переделать через мок-объекты.
Есть тестируемый метод login:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
    public boolean login(String login) throws Exception{
 
        if (checkLogin(login)) {
            userName = login;
            return true;
        }
        return false;
    }
 
    private boolean checkLogin(String login) throws Exception {
        if (connection.isConnected()) {
            try {
                Message message = new Message();
                message.setUser(login);
                message.setCommand(ServerSettings.LOGIN_CHECK);
                connection.sendToServer(message);
 
                message = connection.readFromServer();
                if (ServerSettings.LOGIN_IS_FREE.equals(message.getCommand()))
                    return true;
 
            } catch (Exception e) {
//                System.out.println("Client error:" + e);
                closeConnection();
                throw e;
            }
        }
        return false;
    }
И тест под него:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    @Test
    public void loginIsFree() throws Exception {
        ConnectionToServer connection2 = mock(ConnectionToServer.class);
        String user = "user_name";
 
        Message message = new Message();
        message.setUser(user);
        message.setCommand(ServerSettings.LOGIN_CHECK);
        doNothing().when(connection2).sendToServer(message);
 
        Message answer = new Message("", user, ServerSettings.LOGIN_IS_FREE);
        when(connection2.readFromServer()).thenReturn(answer);
 
        Client c = new Client();
        c.connectToServer(connection2);
        assertTrue(c.login(user));
    }
"Замокал" поведение методов sendToServer и readFromServer, но тест с ошибкой вылетает
java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertTrue(Assert.java:52)

Что тут неверно сделано?
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
27.11.2017, 16:33 4
Да что угодно может быть. Смотря как вы замокали объект, да и вообще как у вас сделано. Вот я на основе ваших кусков сделал синтетику. Посмотрите как замокано здесь (идея в том, что тестируемый объект -- клиент, соответственно операционный кусок -- соединение, замокано так, чтобы давать истину на вашем тесте):
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class Client {
    private String destinationIp;
    private String userName;
 
    private ServerConnection connection;
 
    public Client(String destinationIp) {
        this.destinationIp = destinationIp;
    }
 
    public void connectTo(ServerConnection destinationConnection) {
        connection = destinationConnection;
        connection.establish(destinationIp);
    }
 
    public boolean login(String login) throws Exception {
        if (checkLogin(login)) {
            userName = login;
            return true;
        } else {
            return false;
        }
    }
 
    private boolean checkLogin(String login) throws Exception {
        if (connection.isConnected()) {
            try {
                Message message = new Message("I want to send this");
                message.setUser("evggen0904");
                message.setCommand("This is a command. I'm lazy to make all classes!");
 
                // bla-bla some more code
                connection.send(message);
 
                return true;
            } catch (Exception e) {
                // log and bla-bla
                throw e;
            }
        }
        return false;
    }
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Message {
    private String content;
    private String user;
    private String command;
 
    public Message(String content) {
        this.content = content;
    }
 
    public String getContent() {
        return content;
    }
 
    public void setUser(String user) {
        this.user = user;
    }
 
    public void setCommand(String command) {
        this.command = command;
    }
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class ServerConnection {
    protected boolean isConnectionEstablished;
 
    public ServerConnection() {
        isConnectionEstablished = false;
    }
 
    public boolean isConnected() {
        return isConnectionEstablished;
    }
 
    public void establish(String destinationIp) {
        if ((destinationIp != null) && (destinationIp.length() > 0))
            isConnectionEstablished = true;
        else
            isConnectionEstablished = false;
    }
 
    public void send(Message message) throws Exception {
        Thread.sleep(1000);
    }
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
public class MockedConnection extends ServerConnection {
    @Override
    public void establish(String destinationIp) {
        isConnectionEstablished = true;
    }
 
    @Override
    public void send(Message message) throws Exception {
        // no op
        // NOTE: we never throw here so that Client.checkLogin() never fails.
    }
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
public class ClientTest {
    @Test
    public void testLoginIsFree() throws Exception {
        MockedConnection mockedConnection = new MockedConnection();
 
        Client client = new Client("localhost");
        client.connectTo(mockedConnection);
 
        String userNameToCheck = "hell_knight";
 
        assertTrue(client.login(userNameToCheck));
    }
}
1
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
27.11.2017, 16:35 5
evggen0904, смотрите у себя строки 41 и 52. Ожидали true, получили false.
У Вас в mock'e connection2 isConnected() как думаете что вернет?
2
3 / 3 / 2
Регистрация: 31.07.2017
Сообщений: 29
27.11.2017, 17:01  [ТС] 6
Цитата Сообщение от HighPredator Посмотреть сообщение
Вот я на основе ваших кусков сделал синтетику
Я, вероятно, не очень понятно выразился. То как вы реализовали mock, я сделал в самом начале и тест у меня отработал корректно. А вот реализовать тоже самое при помощи фрэймворка Mockito не получается.

Добавлено через 4 минуты
Разобрался!
Всем спасибо! нужно было замокать выполнение метода isConnected.
0
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
27.11.2017, 18:08 7
дебаггер включи и посмотри
0
614 / 488 / 175
Регистрация: 02.03.2010
Сообщений: 1,238
28.11.2017, 06:14 8
Цитата Сообщение от evggen0904 Посмотреть сообщение
нужно было замокать выполнение метода isConnected.
Ну я же говорил...
Цитата Сообщение от _ViPeR_ Посмотреть сообщение
мокаешь, все что используется при тестировании.
0
28.11.2017, 06:14
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.11.2017, 06:14
Помогаю со студенческими работами здесь

Как на локальной машине тестировать ASP?
Как на локальной машине тестировать ASP? Знаю, что можно, но на 'поиски правды' времени нет.

Как тестировать клиент-серверные приложения?
У меня есть пара вопросов: 1) Что делать, если эмулятор не запускается ни в эклипсе, ни в андроид...

Как тестировать для iphone/Android
Столкнулся с проблемой: вёрстка отображается корректно на десктопе в браузере Firefox с...

Как тестировать Asp.net приложения
полазил по инету в поисках вопроса "Как тестировать Asp.net приложения" понаходил кучу сайтов, но...

Как одновременно тестировать код на разных ЯП?
Доброго времени суток! В процессе олимпиады разные школьники решают одну и ту же задачу на разных...

Как тестировать скрипты PHP с использованием XAMPP?
Здравствуйте. Собрался изучать PHP. Естественно, встал вопрос о тестировании написанных...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru