Странное поведение assertThat (актуально) .usingRecursiveComparison (). IgnoringAllOverriddenEquals (). IsEqualTo (ожидается) - PullRequest
0 голосов
/ 28 марта 2020

Я столкнулся с интересным поведением рекурсивного сравнения в библиотеке assertj. Если вы сравниваете объекты классов, которые являются подклассами, поля суперклассов, кажется, пропускаются во время сравнения. Это известная проблема? Или я что-то не так делаю? Вот краткий пример:

import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;

public class ExampleTest {

  @Test
  public void test() {
    MyException expected =
            new MyException("Expected text message");
    MyException actual = new MyException("Actual text message"); //values for the field Throwable.detailMessage are different
    assertThat(actual).usingRecursiveComparison().ignoringAllOverriddenEquals().isEqualTo(expected);
  }
}

class MyException extends RuntimeException {

  MyException(String message) {
    super(message);
  }
}

Этот тест пройдет, когда на самом деле это не так, как actual.getMessage() и expected.getMessage() покажет разные значения.

1 Ответ

0 голосов
/ 30 марта 2020

Очевидно, что библиотека пропускает сравнение полей, унаследованных от суперклассов, находящихся в java.lang. Поскольку MyException использует поле detailMessage, унаследованное от java.lang.Throwable, оно пропускается. Вот код из org.assertj.core.internal.Objects, который, кажется, отвечает за такое поведение:

/**
   * Returns the declared fields of given class and its superclasses stopping at superclass in <code>java.lang</code>
   * package whose fields are not included.
   *
   * @param clazz the class we want the declared fields.
   * @return the declared fields of given class and its superclasses.
   */
  public static Set<Field> getDeclaredFieldsIncludingInherited(Class<?> clazz) {
    checkNotNull(clazz, "expecting Class parameter not to be null");
    Set<Field> declaredFields = getDeclaredFieldsIgnoringSyntheticAndStatic(clazz);
    // get fields declared in superclass
    Class<?> superclazz = clazz.getSuperclass();
    while (superclazz != null && !superclazz.getName().startsWith("java.lang")) {
      declaredFields.addAll(getDeclaredFieldsIgnoringSyntheticAndStatic(superclazz));
      superclazz = superclazz.getSuperclass();
    }
    return declaredFields;
  }
...