2016-06-20 6 views
0

Привет Я пишу пользовательский Искателя, чтобы проверить два различных объекта, и мой код:Пользовательские matchers с другой объект

public class DetailsMatcher extends ArgumentMatcher <Details> { 

    private final Details expected; 

    private DetailsMatcher(Details expected) { 
     this.expected = expected; 
    } 

    @Override 
    public boolean matches(Object actual) { 
     return ((Request) actual).getId().equals(expected.getId()); 
    } 

    @Override 
    public void describeTo(Description description) { 
     description.appendText(expected == null ? null : expected.toString()); 
    } 

    public static Details valueObjectEq(Details expected) { 
     return argThat(new DetailsMatcher(expected)); 
    } 
} 

И я хочу использовать его в моем тесте, как:

assertThat(requestModel, DetailsMatcher.valueObjectEq(response)); 

Но это два разных объекта, так что он не работает. Я не хочу менять свои объекты только для целей тестирования, так что у нас есть api вроде assertThat, который позволяет передавать другой объект просто полагаться на результат совпадений, а не на то, чтобы заставить его и ожидать того же типа?

ответ

1

Будьте осторожны, чтобы разделить матчи Mockito и Hamcrest. Атрибут Hamcrest или Hamcrest - это экземпляр объекта, например, ваш new DetailsMatcher(expected). При вызове argThat ваш valueObjectEq, кажется, возвращает объект Details, но это неправда: он вернет null, а Mockito сохранит объект во внутреннем стеке. Следовательно, вы никогда не должны звонить argThat вне звонка на when или verify.

Вместо этого измените DetailsMatcher быть типа ArgumentMatcher<Request>, чтобы указать, что ваш Сличитель может работать на любой Request, а не просто Details и сделать конструктор общественности, так что вы можете назвать это так:

assertThat(requestModel, new DetailsMatcher(orderResponse)); 
// or with a static helper method you write: 
assertThat(requestModel, matchesValueObject(orderResponse)); 

A несколько других примечаний:

  • Matcher.matches не должен генерировать исключения, но он будет делать это здесь, если вы передадите запрос без запроса. Обратитесь к instanceof и верните false, если аргумент не является совпадением.
  • Mockito 2.0 делает ArgumentMatcher собственным классом, а не расширением org.hamcrest.Matcher. Если вы хотите использовать Matcher для своих свойств Hamcrest, вам может потребоваться, чтобы он расширил оба варианта, или просто сделайте его совпадением Hamcrest и настройте valueObjectEq для вызова MockitoHamcrest.argThat вместо этого.
  • Хотя сообщение об ошибке не будет ясно, что вы всегда можете вызвать метод вручную:

    assertTrue(new DetailsMatcher(orderReponse).matches(requestModel)); 
    

Смотрите также: