AssertEquals возвращает false для двух одинаковых объектов - PullRequest
0 голосов
/ 21 декабря 2018

У меня есть два пользовательских объекта, содержимое которых одинаково.Но метод assertsEquals inturn equals возвращает false для этих объектов.

здесь - трассировка стека, которая также содержит содержимое toString объектов.

java.lang.AssertionError: expected: com.xyz.test.model.VerificationToken<VerificationToken(id=null, token=, user=User(userId=null, username=null, email=null, password=null, isActive=0, roles=null, imageLocation=null, enabled=false, isAccountNonLocked=true), expiryDate=Sat Dec 22 22:48:49 IST 2018)> but was: com.xyz.test.model.VerificationToken<VerificationToken(id=null, token=, user=User(userId=null, username=null, email=null, password=null, isActive=0, roles=null, imageLocation=null, enabled=false, isAccountNonLocked=true), expiryDate=Sat Dec 22 22:48:49 IST 2018)>
    at org.junit.Assert.fail(Assert.java:88)
    at org.junit.Assert.failNotEquals(Assert.java:834)
    at org.junit.Assert.assertEquals(Assert.java:118)
    at org.junit.Assert.assertEquals(Assert.java:144)
    at ....

Мой соответствующий класс выглядит следующим образом.Здесь есть аннотация @data от lombak, которая генерирует метод Equals.

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class VerificationToken implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 8788934708305097680L;

    private static final int EXPIRATION = 60 * 24;

    @Id
    private Long id;

    private String token;

    private User user; 

    private Date expiryDate;

    public Date calculateExpiryDate(int expiryTimeInMinutes) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.MINUTE, expiryTimeInMinutes);
        return new Date(cal.getTime().getTime());
    }

}

Мой класс User выглядит следующим образом.Здесь также есть аннотация @Data, которая генерирует метод Equals

@Entity
@Table(name = "user")
@Data
public class User implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -6480423780555564185L;

    @Id
    private Integer userId;
    private String username;
    private String email;
    @JsonIgnore
    private String password;

    private int isActive;

    private Set<Role> roles;
    private String imageLocation;   
    private boolean enabled;
    private boolean isAccountNonLocked;

    public User() {
        super();
        this.enabled=false;
        this.isAccountNonLocked= true;
    }

    public User(User user) {
        this.username = user.getUsername();
        this.password = user.getPassword();
        this.isActive = user.getIsActive();
        this.roles = user.getRoles();
        this.imageLocation=user.getImageLocation();
        this.enabled= user.enabled;
        this.isAccountNonLocked = user.isAccountNonLocked;
    }

}

Мой класс роли выглядит следующим образом: здесь также имеется аннотация @Data, которая генерирует метод Equals

@Entity
@Table(name = "role")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Role {

    @Id
    private Integer roleId;
    private String role;

}

Это мойконтрольный пример, содержащий один экземпляр объекта.

@Test
        public void testCreateVerificationToken() {
            User user = new User();
            String token = new String();
            VerificationToken myToken = new VerificationToken();
            myToken.setToken(token);
            myToken.setUser(user);
            myToken.setExpiryDate(myToken.calculateExpiryDate(24*60));
            ArgumentCaptor<VerificationToken> entityCaptor = ArgumentCaptor.forClass(VerificationToken.class);
            when(mocktokenRepository.save(entityCaptor.capture())).thenReturn(myToken);
            verificationTokenServiceImpl.createVerificationToken(user, token);

            assertEquals(entityCaptor.getValue(),myToken);
        }

другой экземпляр объекта происходит в этом коде.

@Override
        public void createVerificationToken(User user, String token) {
            VerificationToken myToken = new VerificationToken();
            myToken.setToken(token);
            myToken.setUser(user);
            myToken.setExpiryDate(myToken.calculateExpiryDate(24*60));
            tokenRepository.save(myToken);
        }

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

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 21 декабря 2018

Date имеет точность в миллисекундах, поэтому даже если две даты выводят одно и то же значение с точностью до секунды, equals может возвращать значение false, поскольку они различаются на миллисекунды.

Вам нужно использоватьбольшая зернистость, чем миллисекунды.Поскольку ваше время истечения в минутах, вы можете использовать его в качестве минимальной единицы времени и установить секунды / миллисекунды в ноль.Вот быстрый способ добиться этого.

public Date calculateExpiryDate(int expiryTimeInMinutes) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(new Date());
    cal.add(Calendar.MINUTE, expiryTimeInMinutes);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    return cal.getTime();
}
0 голосов
/ 21 декабря 2018

Два сравниваемых объекта имеют различное значение в поле expiryDate.Вы генерируете их, используя new Date() для обоих объектов в разных точках кода, используя метод calculateExpiryDate.Они не будут равны.Обратите внимание, что точность даты составляет миллисекунды.Я не буду предлагать вам изменить реализацию calculateExpiryDate для прохождения теста, вместо этого вы можете установить expiryDate в жестко заданное значение Date.

0 голосов
/ 21 декабря 2018

assertEquals вызывает метод equals класса VerificationToken.Вы не переопределяете этот метод, поэтому используется реализация Object по умолчанию, которая проверяет равенство экземпляров (a == b).Если entityCaptor.getValue() не возвращает исходный экземпляр, но, например, сериализованную или клонированную копию, этот тест не пройден.

Если вы ожидаете, что будет возвращен тот же экземпляр, вы должны использовать assertSame и исправить ошибку, котораяпривести к возвращению другого экземпляра.Если вы ожидаете, что будет возвращен другой экземпляр, вы должны сначала выполнить assertNotSame, внедрить equals и hashcode в VerificationToken и выполнить assertEquals после assertNotSame.

...