Я думаю, что в первую очередь стоит сказать, что такое тестирование внутренних классов не очень хорошая идея, за исключением, может быть, очень особых случаев. Ваши тесты будут хрупкими, и изменения, которые обычно были бы абсолютно безопасными, т. Е. Переименование поля, теперь могут привести к сбою автоматической сборки. Вы должны проверить внешнее поведение , а не детали реализации.
Кажется, вам лучше реализовать equals
и hashCode
в вашем классе A
, так что вы можете просто сделать:
contains(new A(1))
С учетом сказанного, если у вас есть действительно веская причина для этого (а такие случаи будут редкими), вы не сможете использовать hasProperty
для этого.
С JavaDoc :
Создает средство сопоставления, которое соответствует, когда исследуемый объект имеет JavaBean
свойство с указанным именем, значение которого удовлетворяет указанному
согласовани.
Полагаю, это подразумевает, что вам потребуется метод с именем getX
.
Вы не должны добавлять такой метод только для целей теста, но вы можете написать свою собственную реализацию Matcher
общего назначения, которая будет использовать отражение для проверки полей класса.
Вот пример реализации:
class ReflectiveFieldMatcher<T> extends BaseMatcher<Object>
{
private final String fieldName;
private final T expectedValue;
ReflectiveFieldMatcher(final String fieldName, final T expectedValue)
{
this.fieldName = fieldName;
this.expectedValue = expectedValue;
}
@Override
public boolean matches(final Object obj)
{
for (final Field field : obj.getClass().getFields())
{
if (field.getName().equals(fieldName))
{
field.setAccessible(true);
try
{
Object value = field.get(obj);
return expectedValue.equals(value);
}
catch (final IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
}
return false;
}
@Override
public void describeTo(final Description description)
{
description.appendText("Object with field '" + fieldName + "' with value: " + expectedValue);
}
}
Ваш пример теперь будет выглядеть так:
assertThat(result, contains(new ReflectiveFieldMatcher<>("x", 1)));