#java #unit-testing
#java #модульное тестирование
Вопрос:
Мой профессор дал нам это домашнее задание и создал проект с кучей модульных тестов. Наша цель — убедиться, что мы можем пройти эти модульные тесты. У нас есть три класса. Класс под названием Person с именем и возрастом, говорящий класса, который расширяет Person, и посетитель класса, который также расширяет Person. Я изо всех сил пытаюсь убедиться, что нет повторяющихся людей. generateRandomString()
был реализован профессором и просто возвращает случайную строку.
Я уже создал класс, его конструктор, средства получения и установки. Я также переопределил метод equals()
в классе Person
Это тест, который дал нам наш профессор:
@Test
public void testNoDuplicatePerson() {
HashSet<Person> people = new HashSet<Person>();
String name = generateRandomString();
Person p = new Speaker(name);
people.add(p);
assertEquals(1,people.size());
p = new Attendee(name);
people.add(p);
assertEquals(1,people.size());
}
Как я могу пройти этот тест?
РЕДАКТИРОВАТЬ: я решил опубликовать код трех классов:
Person
```java
public abstract class Person {
private String name;
private int age;
public Person(String name) {
this.name = name;
this.age = 0;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean equals(Object o) {
if (o == null || !(o instanceof Person))
return false;
Person converted = (Person) o;
if (this.getName().equals(converted.getName()) amp;amp; this.getAge() == converted.getAge())
return true;
return false;
}
}
Докладчик:
public class Speaker extends Person {
private int fee;
public Speaker(String name) {
super(name);
this.fee = 0;
}
public Speaker(String name, int age) {
super(name, age);
this.fee = 0;
}
public Speaker(String name, int age, int fee) {
super(name, age);
this.fee = fee;
}
public int getFee() {
return fee;
}
public void setFee(int fee) {
this.fee = fee;
}
public String toString() {
return "Speaker " this.getName() " as a fee value of " this.getFee() ".";
}
}
Участник:
public class Attendee extends Person {
private boolean paid;
public Attendee(String name) {
super(name);
this.paid=false;
}
public Attendee(String name, int age) {
super(name, age);
this.paid=false;
}
public boolean hasPaid(){
if (this.paid==true)
return true;
return false;
}
public String toString(){
return "Attendee " this.getName() (this.hasPaid() ? " has":" hasn't") " paid its registration.";
}
}
Комментарии:
1. Что говорит javadoc из HashSet? Когда набор считает, что объект является дубликатом другого объекта? К какому выводу вы пришли? docs.oracle.com/javase/8/docs/api/java/util/HashSet.html#add-E —
2. Вы не должны изменять сам модульный тест, только свой код. Насколько я понял, я не смогу создать
Person
объект, если у меня уже естьPerson
объект с определенным именем. Строка кодаPerson p=new Speaker(name);
не должна работать, поскольку у меня уже есть пользователь с таким именем. Мой вопрос в том, как это решить3. Нет. Вы можете иметь столько пользователей с одинаковыми именами, сколько захотите. Это не то, что тест проверяет. Тест проверяет то, что, если вы пытаетесь добавить пользователя в хэш-набор с тем же именем, что и у другого пользователя, уже находящегося в хэш-наборе, то хэш-набор должен рассматривать их как дубликаты (поскольку размер набора остается равным 1 после добавления). Отсюда мой вопрос: когда set считает, что объект является дубликатом другого объекта?
4. Из документации Java: »
public boolean add(E e)
Добавляет указанный элемент в этот набор, если он еще не присутствует. Более формально, добавляет указанный элемент e к этому набору, если этот набор не содержит элемента e2, такого что (e==null ? e2==null : e.равно(e2)). Если этот набор уже содержит элемент, вызов оставляет набор неизменным и возвращает false.» Я, очевидно, должен переопределить метод equals.5. Вы все поняли правильно.
Ответ №1:
Как упоминалось @JB Nizet, когда вы переопределяете equals
метод класса, вы должны переопределить hashCode
метод. Обратите внимание на имя класса в тесте JUnit: набор хэшей. Это зависит от hashCode
метода. Решение:
a. Научитесь читать документы java API. Вот ссылка на JavaDocs версии 8. Прочитайте HashSet
страницу.
b. Реализуйте hashCode
метод. У вас явно есть доступ в Интернет, поэтому, если вы не знаете, как реализовать hashCode
метод, попробуйте поискать в Google «как мне реализовать метод Java hashCode».
Подсказка: String уже реализует метод hashCode.