Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
36 / 3 / 0
Регистрация: 21.05.2018
Сообщений: 111

Тестирование вспомогательных методов

17.09.2018, 13:41. Показов 3200. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
И еще один вопрос по тестированию... Нужно ли тестировать вспомогательные методы? Они как правило закрыты. Например, есть метод, который парсит xml файл:
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
private void parseNodeList(NodeList childNodes, Employee employee) {
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node nextChildNode = childNodes.item(i);
                if (nextChildNode.getNodeType() == Node.ELEMENT_NODE) {
                    if (nextChildNode.getNodeName().equals("id"))
                        employee.setId(Integer.parseInt(nextChildNode.getTextContent()));
                    if (nextChildNode.getNodeName().equals("name"))
                        employee.setName(nextChildNode.getTextContent());
                    if (nextChildNode.getNodeName().equals("base"))
                        employee.setBase(Double.parseDouble(nextChildNode.getTextContent()));
                    if (nextChildNode.getNodeName().equals("workTime"))
                        employee.setWorkTime(Double.parseDouble(nextChildNode.getTextContent()));
                    if (nextChildNode.getNodeName().equals("position"))
                        employee.setPosition(nextChildNode.getTextContent());
                    if (nextChildNode.getNodeName().equals("subordinates"))
                        employee.setSubordinates(Integer.parseInt(nextChildNode.getTextContent()));
                    if (nextChildNode.getNodeName().equals("project")) {
                        Element element = (Element) nextChildNode;
                        double budget = Double.parseDouble(element.getAttribute("budget"));
                        NodeList projectList = ((Element) nextChildNode).getElementsByTagName("personalInput");
                        double personalInput = Double.parseDouble(projectList.item(0).getTextContent());
                        Double[]arr={budget,personalInput};
                        NodeList projectList2 = ((Element) nextChildNode).getElementsByTagName("title");
                        String projectTitle = projectList2.item(0).getTextContent();
                        employee.getProject().put(projectTitle,arr);
                    }
 
                }
            }
        }
или который выполняет инициализацию объектов из списка:
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
44
private void loadStaff() throws ParserConfigurationException, IOException, SAXException {
            String[] pos = {"Cleaner", "Driver", "Programmer", "Tester", "TeamLeader", "Manager", "ProjectManager", "SeniorManager"};
            Employee employee = null;
            AccountingDepartment accountingDepartment = new AccountingDepartment();
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node nextNode = nodeList.item(i);
                if (nextNode.getNodeType() == Node.ELEMENT_NODE) {
                    for (int j = 0; j < pos.length; j++) {
                        if (nextNode.getNodeName().equals(pos[j])){
                            switch (j) {
                                case 0:
                                    employee = new Cleaner();
                                    break;
                                case 1:
                                    employee = new Driver();
                                    break;
                                case 2:
                                    employee = new Programmer();
                                    break;
                                case 3:
                                    employee = new Tester();
                                    break;
                                case 4:
                                    employee = new TeamLeader();
                                    break;
                                case 5:
                                    employee = new Manager();
                                    break;
                                case 6:
                                    employee = new ProjectManager();
                                    break;
                                case 7:
                                    employee = new SeniorManager();
                                    break;
                            }
                        }
                    }
                    employees.add(employee);
                    NodeList childNodes = nextNode.getChildNodes();
                    parseNodeList(childNodes, employee);
                    employee.setPayment(accountingDepartment.getPayment(employee));
                }
            }
        }
Не совсем понятно... Или может методы нужно отрефакторить как-то.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.09.2018, 13:41
Ответы с готовыми решениями:

Тестирование методов
Здравствуйте! Такая проблема: если допустим есть метод public int sum(int first, int second) { return first + second; ...

Тестирование приватных методов.
Подскажите пожалуйст,как можо тестировать приватные методы с помощю JUnit ? Мне говорили что с помощю Рефлексии,но я почитал и не понял...

Тестирование методов через JUnit
Доброго времени суток Помогите пожалуйста. Есть такой метод для удаления файлов private void deleteFile(FileElement fi) { ...

27
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
17.09.2018, 14:11
for-if-for-if-switch - таки нужно рефакторить. Хотя бы отдельные методы выделить. Зачем if перед switch так же не ясно.

Вы же тестируете публичное API. По хорошему тестами должны быть покрыты все возможные варианты работы. Я это к тому, что не важно весь код у Вас в одном тестируемом методе или же этот метод вызывает какие-то еще методы (конечно если это не методы из других классов, которые надо mock'ать). Вы же что-то подаете на вход и проверяете что получается на выходе.
1
36 / 3 / 0
Регистрация: 21.05.2018
Сообщений: 111
17.09.2018, 23:22  [ТС]
Цитата Сообщение от JIeIIIa Посмотреть сообщение
Зачем if перед switch так же не ясно.
- здесь я определяю какой объект создать. В списке NodeList ряд различных позиций по профессиям. Проверяется соответствие имени Node с названием элемента массива по индексу. Создаваемый объект также ставится в соответствие с индексом элемента массива.
Цитата Сообщение от JIeIIIa Посмотреть сообщение
for-if-for-if-switch - таки нужно рефакторить
- попробую что-нибудь сделать... Спасибо!

Добавлено через 2 минуты
Хотя выделить отдельные методы будет довольно проблематично...

Добавлено через 13 минут
Цитата Сообщение от JIeIIIa Посмотреть сообщение
Вы же что-то подаете на вход и проверяете что получается на выходе.
- дело в том, что потом все эти Employee просто выводятся в виде списка.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void printStaff(){
            class Format{
                Formatter f = new Formatter(System.out);
 
                void printHeadPersonal(){
                    f.format("%-5s %15s %38s %12s %20s %9s\n","ID", "ФИО", "Должность", "Ставка", "Отработанное время","Зарплата");
                    f.format("%-5s %15s %35s %14s %13s %15s\n","---","---","---","---","---","---");
                }
                void printEmployee(Employee employee){
                    f.format("%-5d %-35s %-25s %5.1f %13.1f %16.1f \n", employee.getId(), employee.getName(), employee.getPosition(),
                            employee.getBase(), employee.getWorkTime(), employee.getPayment());
                }
            }
 
            Format format = new Format();
            format.printHeadPersonal();
            for (Employee employee:employees){
                       format.printEmployee(employee);
            }
        }
Есть еще конечно класс, методы которого считают зарплату. Там с тестами проблем не будет.
0
 Аватар для Aviz__
2739 / 2048 / 507
Регистрация: 17.02.2014
Сообщений: 9,468
18.09.2018, 09:15
Цитата Сообщение от Njula Посмотреть сообщение
Спасибо!
можно нажать "+1 Спасибо"... JIeIIIa, почему-то это любит))
0
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
18.09.2018, 10:30
Лучший ответ Сообщение было отмечено Njula как решение

Решение

Если не ошибаюсь, этот код
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
for (int j = 0; j < pos.length; j++) {     //в цикле перебираем все элементы массива
   if (nextNode.getNodeName().equals(pos[j])){  //проверяем что имя ноды совпадает с элементом массива (но т.к. в массиве уникальные элементы, то после совпадения нет смысла перебирать остальные элементы)
      switch (j) {   //а теперь зная индекс выбираем нужный вариант
         case 0:
            employee = new Cleaner();
            break;
         case 1:
            employee = new Driver();
            break;
         case 2:
            employee = new Programmer();
            break;
         case 3:
            employee = new Tester();
            break;
         //...
      }
   }
}
эквивалентен этому:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   switch (nextNode.getNodeName()) {  //по имени ноды выбираем что создать
      case "Cleaner":
         employee = new Cleaner();
         break;
      case "Driver":
         employee = new Driver();
         break;
      case "Programmer":
         employee = new Programmer();
         break;
      case "Tester":
         employee = new Tester();
         break;
      //...
   }
Если массив pos используется в нескольких местах, то выделить его елементы как константы класса или же элементы enum.
1
36 / 3 / 0
Регистрация: 21.05.2018
Сообщений: 111
18.09.2018, 10:43  [ТС]
Цитата Сообщение от Aviz__ Посмотреть сообщение
можно нажать "+1 Спасибо"... JIeIIIa, почему-то это любит))
- а я разве не нажал? Мое упущение..))
0
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
18.09.2018, 10:45
Цитата Сообщение от Njula Посмотреть сообщение
все эти Employee просто выводятся в виде списка
Как вариант:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Format{
   String printHeadPersonal(){
      return String.format("%-5s %15s %38s %12s %20s %9s\n","ID", "ФИО", "Должность", "Ставка", "Отработанное время","Зарплата") +
                String.format("%-5s %15s %35s %14s %13s %15s\n","---","---","---","---","---","---");
   }
   String printEmployee(Employee employee){
      return String.format("%-5d %-35s %-25s %5.1f %13.1f %16.1f \n", employee.getId(), employee.getName(), employee.getPosition(), employee.getBase(), employee.getWorkTime(), employee.getPayment());
   }
}
 
 
public void printStaff(Format format){  //тут нет привязки к конкретному формату; при тесте передаете mock и проверяете какой метод и сколько раз вызывался
            System.out.print(format.printHeadPersonal());
            for (Employee employee:employees){
                       System.out.print(format.printEmployee(employee));
            }
        }
1
36 / 3 / 0
Регистрация: 21.05.2018
Сообщений: 111
18.09.2018, 11:04  [ТС]
Цитата Сообщение от JIeIIIa Посмотреть сообщение
Если массив pos используется в нескольких местах, то выделить его элементы как константы класса или же элементы enum.
- Все верно, спасибо! Я сейчас думаю, что можно вообще обойтись без switch. Можно ведь создать map, которые будут содержать ключи - названия профессий и значения - соответствующие объекты Class, вызов просто производить по getKey, и создавать объекты newInstance. Совсем недавно читал об таких вещах. Когда делал эту программу не знал...

Добавлено через 8 минут
Цитата Сообщение от JIeIIIa Посмотреть сообщение
при тесте передаете mock и проверяете какой метод и сколько раз вызывался
- хмм, пока, честно говоря, не представляю как это можно сделать...

Добавлено через 34 секунды
как проверить, сколько раз вызывался тот или иной метод?
0
 Аватар для Aviz__
2739 / 2048 / 507
Регистрация: 17.02.2014
Сообщений: 9,468
18.09.2018, 11:05
Цитата Сообщение от Njula Посмотреть сообщение
Когда делал эту программу не знал
так, переделай)) практика не лишнее в нашем деле...
0
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
18.09.2018, 11:07
Цитата Сообщение от Njula Посмотреть сообщение
как это можно сделать...
Шесть простых примеров по Mockito (перевод) Остальное спросите у гугла)
1
36 / 3 / 0
Регистрация: 21.05.2018
Сообщений: 111
18.09.2018, 11:11  [ТС]
Цитата Сообщение от Aviz__ Посмотреть сообщение
так, переделай)) практика не лишнее в нашем деле...
конечно) так и сделаю, код получится куда более компактным.

Добавлено через 43 секунды
JIeIIIa, спасибо!
0
 Аватар для Aviz__
2739 / 2048 / 507
Регистрация: 17.02.2014
Сообщений: 9,468
18.09.2018, 11:29
Цитата Сообщение от Njula Посмотреть сообщение
как проверить, сколько раз вызывался тот или иной метод?
вот так, влоб, не?
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
public class TestScena {
 
 
   public static void main(String[] args) {
        Aaa ob10Aaa = new Aaa();
        Aaa ob11Aaa = new Aaa();
        for (int i = 1; i <= 20; i++) {
            ob10Aaa.method();
            if (i % 4 == 0)
                ob10Aaa.printCounter();
        }
        ob11Aaa.method();
        ob10Aaa.printCounter();
    }
}
//####
class Aaa {
    private static int counterForMethod = 0;
 
    public void method() {
        Aaa.counterForMethod++;
    }
 
    public void printCounter() {
        System.out.println(Aaa.counterForMethod);
    }
}
0
36 / 3 / 0
Регистрация: 21.05.2018
Сообщений: 111
18.09.2018, 12:02  [ТС]
Цитата Сообщение от Aviz__ Посмотреть сообщение
вот так, влоб, не?
Java
- это понятно. Но задача стоит несколько иная. Есть List с различными Employee, которые выводятся списком методом
Цитата Сообщение от JIeIIIa Посмотреть сообщение
public void printStaff(Format format)
Что даст подсчет количества вызываемых методов(при выводе на печать?)? Эти методы есть в каждом Employee. Разве что количество созданных объектов? Нужно ли вводить в класс специальный метод для подсчета вызовов в тесте?

Добавлено через 1 минуту
Aviz__, вопросов много. Пытаюсь все осмыслить. Для меня тесты это нечто новое.

Добавлено через 1 минуту
Кстати вот как изменился метод... Еще бы покомпактнее можно было создать Map...
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
private void loadStaff() throws ParserConfigurationException, IOException, SAXException, IllegalAccessException, InstantiationException {
 
            AccountingDepartment accountingDepartment = new AccountingDepartment();
            Employee employee = null;
            Map<String, Class<? extends Employee>> map = new TreeMap();
            map.put("Cleaner", Cleaner.class);
            map.put("Driver", Driver.class);
            map.put("Programmer", Programmer.class);
            map.put("Tester", Tester.class);
            map.put("TeamLeader", TeamLeader.class);
            map.put("Manager", Manager.class);
            map.put("ProjectManager", ProjectManager.class);
            map.put("SeniorManager", SeniorManager.class);
 
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node nextNode = nodeList.item(i);
                if (nextNode.getNodeType() == Node.ELEMENT_NODE) {
                    if (map.containsKey(nextNode.getNodeName()))
                    employee = map.get(nextNode.getNodeName()).newInstance();
                    employees.add(employee);
                    NodeList childNodes = nextNode.getChildNodes();
                    parseNodeList(childNodes, employee);
                    employee.setPayment(accountingDepartment.getPayment(employee));
                }
            }
        }
0
 Аватар для Aviz__
2739 / 2048 / 507
Регистрация: 17.02.2014
Сообщений: 9,468
18.09.2018, 12:27
Цитата Сообщение от Njula Посмотреть сообщение
Пытаюсь все осмыслить
все получится, Бро))! Главное не сдавайся!!!
0
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
18.09.2018, 12:34
Цитата Сообщение от Njula Посмотреть сообщение
Нужно ли вводить в класс специальный метод для подсчета вызовов в тесте?
Нет! Не захламляйте классы. Почитайте более подробно про Mockito.
Цитата Сообщение от Njula Посмотреть сообщение
Что даст подсчет количества вызываемых методов(при выводе на печать?)?
Например, что Вы передали n элементов и для них n раз вызвался метод печати.

Добавлено через 3 минуты
Цитата Сообщение от Aviz__ Посмотреть сообщение
private static int counterForMethod = 0;
И зачем такие костыли городить в каждый класс, в котором я захочу проверить сколько раз вызывался метод? А если методов больше одного держать для них Map?
1
36 / 3 / 0
Регистрация: 21.05.2018
Сообщений: 111
18.09.2018, 12:36  [ТС]
Всем спасибо! Сдаваться - это не про меня)).

Добавлено через 1 минуту
Цитата Сообщение от JIeIIIa Посмотреть сообщение
И зачем такие костыли городить в каждый класс, в котором я захочу проверить сколько раз вызывался метод? А если методов больше одного держать для них Map?
- это я понимаю). Изучаю Mockito...
0
18.09.2018, 13:21

Не по теме:

Цитата Сообщение от JIeIIIa Посмотреть сообщение
И зачем такие костыли
Даже не предполагал, вашу степень занудства и неспособности мыслить шире! Ну, ничего, бывает((. Вы тоже держитесь, думаю, вам очень не просто...

0
18.09.2018, 13:28

Не по теме:

Aviz__, сходите лучше в Дебагер. Возможно, я стану Вас меньше раздражать...

0
18.09.2018, 13:37

Не по теме:

Цитата Сообщение от JIeIIIa Посмотреть сообщение
сходите лучше в Дебагер
cпасибо! где находится ваш исходник?
Цитата Сообщение от JIeIIIa Посмотреть сообщение
я стану Вас меньше раздражать
вы опять себе льстите! Бро, вы так долго не протяните...

0
36 / 3 / 0
Регистрация: 21.05.2018
Сообщений: 111
18.09.2018, 23:33  [ТС]
JIeIIIa, можно вопросик по Mockito? Не совсем понимаю... Заглушка это понятно. Делаю заглушку для объекта Format. Вызываю метод основного класса Main printStaff, который собственно и тестируется, передаю ему в качестве аргумента заглушку. Заглушка хранит в себе информацию о вызовах его методов. Хорошо. Вызываю метод Main loadStaff (надо же что-то перебирать в цикле printStaff) - правда что-то мне подсказывает что этого делать не нужно, этот метод закрытый. В методе подсчета вызовов передаю методу printEmployee опять же заглушку mockEmployee. В итоге выдаются null для объектов, и ошибка. В общем что-то я запутался... Ковыряюсь, ковыряюсь...
Java
1
2
3
4
5
6
7
8
9
@Test
    public void printStaff() throws Exception {
 
        Main.Format mockFormat = mock(Main.Format.class);
        Employee mockEmployee = mock(Employee.class);
        main.printStaff(mockFormat);
        mockFormat.printEmployee(mockEmployee);
        verify(mockFormat, times(1)).printEmployee(mockEmployee);
    }
А так работает хорошо). Выводит null...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.09.2018, 23:33
Помогаю со студенческими работами здесь

Тестирование методов, возвращающие сложные объекты
Привет! Тестируется все JUnit. Вот вопрос тут возник. Если методы, которые возвращают коллекции объектов. Руками их создавать -...

Завершающий слеш в тегах вспомогательных HTML методов
Доброго времени суток. Столкнулся с такой проблемой при использовании вспомогательных HTML методов. При использовании методов вроде ...

Тестирование приватных классов/методов
Не могу понять как мне тестировать приватные модули. Если я создаю тестовый проект для моего проекта, даю ему ссылку на мой проект и...

Юнит тестирование методов, работающих с файлами
Всем доброго времени суток! Возникла у меня небольшая проблема с тестированием методов, которые выполняют сериализацию объекта в XML, JSON....

Тестирование закрытых методов через разделяемые классы
Я - большой любитель тестирования непубличных методов. Связано это с тем, что обычно публичных методов у меня немного и работают они через...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru