JUnit тестирование статического счетчика объектов

62
4

Я новичок в модульном тестировании, и у меня есть некоторые сбои, которые я не знаю, как их решить. Я пытался проверить мой простой класс Employee, где у меня есть статический счетчик созданных объектов, поэтому новые сотрудники могут получать последовательные номера и имена по умолчанию, такие как "Name1", "Name2" и т.д. Вот мой блок initiaiton по умолчанию:

    {
currentNr = ++count;
setName("Name"+currentNr);
setSurname("Surname"+currentNr);
}

Я написал один класс JUnit с несколькими методами. Они работают нормально, но методы, относящиеся к счетчику, работают только тогда, когда я запускаю их отдельно (они также работали, когда я сохранил их как отдельные тесты, но, похоже, было грязно, так много файлов). Когда я запускаю класс со всеми методами тестирования, счетчик добавляет больше объектов, и я не знаю, почему/когда/где, поскольку тест независим. В методах тестирования я создаю объект и проверяю счетчик с assertEqual. В поисках решений я пытался работать с @Before, @After и т.д., Но это было то же самое или, может быть, я не знаю, как правильно его использовать. Мой вопрос заключается в том, что я могу сделать, чтобы все методы тестирования работали или что я должен писать в методе @Before (я попытался добавить и удалить объекты в ArrayList и/или установить значение null). Я думаю, что неприемлемо, чтобы тест работал только при запуске отдельно. Любая помощь будет оценена. Благодарю!

спросил(а) 2021-01-25T13:35:51+03:00 4 месяца, 2 недели назад
1
Решение
63

Не используйте статическое поле в качестве счетчика сотрудников. Вместо этого используйте поле экземпляра:

public class Manager {
private int employeesCount;

public Employee addEmployee() {
employeesCount++;
Employee employee = new Employee();
employee.setName("John " + employeesCount);
employee.setLastName("Smith " + employeesCount);
return employee;
}
}

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

Вместо этого убедитесь, что в вашей программе есть только один экземпляр менеджера, и все работают с ним (это называется singleton). Ну, есть одноэлементный узор. И многие веские причины не использовать его (читай: почему синглтоны плохие). Таким образом, это заканчивается тем фактом, что когда вы пишете реальное приложение, вы обычно используете некоторую инфраструктуру инъекций зависимостей (например, весну или гусь), и у них есть возможность создавать синглтон для вас, когда вы этого хотите.

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

ответил(а) 2021-01-25T13:35:51+03:00 4 месяца, 2 недели назад
45

Ответ frenzykryger дает много ценного понимания, но есть немного больше.

Вы всегда должны смотреть на свою работу с SOLID в виду. В вашем примере "принцип единой ответственности" может помочь в более эффективном решении. Понимаете, хорошее программирование OO - это создание полезных абстракций. И некоторые абстракции, которые вы вкладываете в Employee, просто не принадлежат.

Например, можно создать класс Employee для моделирования человека, работающего в какой-либо компании. Итак, сотрудники - люди, поэтому, возможно, у них есть имена; и поскольку они являются частью организации, да, они могут иметь идентификатор.

Но: сотрудник получает удостоверение личности! Когда вы начинаете работу в новой компании, люди не приходят и не спрашивают вас: "Пожалуйста, сообщите нам свой новый цифровой идентификатор". Вместо этого кто-то приходит к вам и говорит вам: "Это ваш цифровой идентификатор, не забывайте".


Поэтому, имея в виду, некоторые советуют:

У сотрудника нет настроек для основных атрибутов. Таким образом, свойства, такие как "ID" или "имя", которые не должны быть изменены, должны передаваться в качестве аргументов конструктору. Вы просто не создаете объект employee и позже можете изменить имя или идентификатор этого объекта! Итак, как правильно ответил другой ответ: какой-то внешний класс, как "Менеджер", должен отслеживать всех "известных" сотрудников; и если новый добавлен, этот Менеджер каким-то образом вычисляет новый уникальный идентификатор.

Наконец: это действительно так: статичность - ненормальность в хорошем дизайне OO. Нужно иметь действительно веские причины обратиться к статическим полям (кроме, может быть, констант) и методам. static всегда приводит к плотно связанному коду - и что-то, чего нужно избегать!

ответил(а) 2021-01-25T13:35:51+03:00 4 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема