source

특정 속성을 가진 요소를 포함한다고 단언하려면 어떻게 해야 합니다.

goodcode 2022. 9. 20. 23:59
반응형

특정 속성을 가진 요소를 포함한다고 단언하려면 어떻게 해야 합니다.

다음 시그니처를 사용하여 메서드를 유닛테스트한다고 가정합니다.

List<MyItem> getMyItems();

MyItem인데, 그 중 가 포조이다.그 중 하나는"name"를 통해 할 수 있습니다.getName().

이 있는 은, 「 」의 「 」의 되고 있는 것 뿐입니다.List<MyItem> 임의의 「」를 지정합니다.Iterable2개의 2개의 2개의 2개의 2개의 2개의 2개의 2개의 2개의 2개의 2개의 2개의 2개의 MyItem, 인스턴스, 인스턴스, 인스턴스, 인스턴스, 인스턴스"name"."foo" ★★★★★★★★★★★★★★★★★」"bar"다른 속성이 일치하지 않는 경우 이 테스트의 목적은 그다지 중요하지 않습니다.이름이 일치하면 성공적인 테스트입니다.

가능하면 원라이너로 해 주셨으면 합니다.여기 제가 하고 싶은 종류의 "의사 구문"이 있습니다.

assert(listEntriesMatchInAnyOrder(myClass.getMyItems(), property("name"), new String[]{"foo", "bar"});

햄크레스트가 이런 종류의 일에 적합할까요?만약 그렇다면, 위의 의사 구문 중 가장 엉성한 버전은 무엇일까요?

올바른 방향으로 안내해 주신 @Razvan님 감사합니다.나는 그것을 한 줄에 넣을 수 있었고 Hamcrest 1.3의 수입품을 성공적으로 찾아냈다.

Import:

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;

코드:

assertThat( myClass.getMyItems(), contains(
    hasProperty("name", is("foo")), 
    hasProperty("name", is("bar"))
));

는 Assert J의 뛰어난 합니다.extracting()할 수 있습니다.Function를 사용하여를 추출합니다.s: "필드를 추출합니다.컴파일 시 체크가 제공됩니다.
먼저 크기를 강조할 수도 있습니다.

다음과 같은 효과를 얻을 수 있습니다.

import static org.assertj.core.api.Assertions;

Assertions.assertThat(myClass.getMyItems())
          .hasSize(2)
          .extracting(MyItem::getName)
          .containsExactlyInAnyOrder("foo", "bar"); 

containsExactlyInAnyOrder()는 이 리스트에는 순서에 관계없이 이들 값만 포함되어 있다고 단언합니다.

에 이러한 되어 있지만 수 있음을 하려면 을 사용하십시오.contains():

.contains("foo", "bar"); 

로 : 사 of 합니다.List에서는 각 을 AssertJ로 로 만듭니다tuple() 삭제:

import static org.assertj.core.api.Assertions;
import static org.assertj.core.groups.Tuple;

Assertions.assertThat(myClass.getMyItems())
          .hasSize(2)
          .extracting(MyItem::getName, MyItem::getOtherValue)
          .containsExactlyInAnyOrder(
               tuple("foo", "OtherValueFoo"),
               tuple("bar", "OtherValueBar")
           ); 

특별히 햄크레스트는 아니지만 여기서 언급할 가치가 있다고 생각합니다.Java8에서 자주 사용하는 것은 다음과 같습니다.

assertTrue(myClass.getMyItems().stream().anyMatch(item -> "foo".equals(item.getName())));

(로드리고 만야리의 약간의 향상에 편집.좀 덜 장황하네요.코멘트를 참조해 주세요).

조금 읽기 어려울지도 모르지만, 활자와 리팩터링의 안전성이 마음에 듭니다.또한 필터 람다에 자바와 같은 && 표현과 함께 여러 콩 특성을 조합하여 테스트하는 경우에도 좋습니다.

시험:

assertThat(myClass.getMyItems(),
                          hasItem(hasProperty("YourProperty", is("YourValue"))));

Assertj 잘해요.

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

    assertThat(myClass.getMyItems()).extracting("name").contains("foo", "bar");

hamcrest에 비해 assertj의 큰 장점은 코드 완성을 쉽게 사용할 수 있다는 것입니다.

리스트가 구체적인 클래스인 경우 MyItem에서 equals() 메서드를 구현하고 있는 한 contains() 메서드를 호출할 수 있습니다.

// given 
// some input ... you to complete

// when
List<MyItems> results = service.getMyItems();

// then
assertTrue(results.contains(new MyItem("foo")));
assertTrue(results.contains(new MyItem("bar")));

단언할 값을 받아들이는 생성자를 구현했다고 가정합니다.이것이 한 줄에 있는 것이 아니라는 것은 알지만, 어느 값이 누락되었는지 알아두는 것이 한 번에 확인하는 것보다 유용합니다.

AssertJ 3.9.1은 다음에서 직접 술어 사용을 지원합니다.anyMatch방법.

assertThat(collection).anyMatch(element -> element.someProperty.satisfiesSomeCondition())

이것은 일반적으로 임의로 복잡한 상태에 적합한 사용 사례입니다.

간단한 조건이라면 다음을 사용하는 것이 좋습니다.extracting(위 참조)를 참조해 주세요.그 이유는, 테스트중의 반복 가능한 결과, 보다 읽기 쉬운 값 검증을 서포트할 수 있기 때문입니다.예: 다음과 같은 특수 API를 제공할 수 있습니다.containsFrank Neblung의 답변에 있는 방법.또는 전화하실 수 있습니다.anyMatch어쨌든 나중에 그것에 대해 설명하고 다음과 같은 방법 참조를 사용합니다."searchedvalue"::equals. 또한 여러 개의 추출기를 설치할 수 있습니다.extracting메서드, 그 후에 검증되는 결과tuple().

다른 방법으로는hasProperty햄크레스트 더 많은 매처들을 시도해 볼 수 있다 where추출 기능이 있는 매처.이 경우 다음과 같습니다.

import static com.github.seregamorph.hamcrest.MoreMatchers.where;

assertThat(myClass.getMyItems(), contains(
    where(MyItem::getName, is("foo")), 
    where(MyItem::getName, is("bar"))
));

이 접근방식의 장점은 다음과 같습니다.

  • 값이 get-method로 계산되는지 여부를 항상 필드별로 확인할 수 있는 것은 아닙니다.
  • 일치하지 않는 경우 진단에서 오류 메시지가 나타납니다(해결된 메서드 참조 MyItem.getName:
Expected: iterable containing [Object that matches is "foo" after call
MyItem.getName, Object that matches is "bar" after call MyItem.getName]
     but: item 0: was "wrong-name"
  • Java 8, Java 11 및 Java 14에서 작동합니다.

Stream을 사용하면 다음 작업도 수행할 수 있습니다.

List<String> actual = myList.stream().map(MyClass::getName).collect(toList());
assertThat(actual, hasItem("expectedString1"));

왜냐하면anyMatch()또는allMatch()목록 내의 일부 값이 목록에 포함되어 있는 것을 알고 있지만 실제 목록에는 5개의 값만 포함되어 있을 가능성이 있습니다.anyMatch()6이 있습니다. 모든 값이 존재하는지 여부를 알 수 없습니다.와 함께hasItem()원하는 값을 모두 체크합니다.

언급URL : https://stackoverflow.com/questions/12166415/how-do-i-assert-an-iterable-contains-elements-with-a-certain-property

반응형