개발 공부/Java
Java에서 List 를 테스트해보자
개발인생
2023. 7. 6. 18:21
반응형
테스트 코드를 작성하다보면 List
를 테스트할 상황이 많이 발생한다.
그 동안은 아무 생각없이 get
을 사용해 테스트하는 방식을 주로 사용했다.
@Test
@DisplayName("List 테스트")
void test20230629131424() {
List<String> testList = Arrays.asList("test1", "test2", "test3");
assertThat(testList.get(0)).isEqualTo("test1");
}
개인적으로 위의 테스트 코드를 작성하며 여러가지 문제점을 겪었다.
get
을 사용해 직접 값을 꺼내오기 때문에List
안의 다른 값들을 테스트하려면 코드의 중복이 발생한다.- 순서가 중요하지 않더라도
List
안의 값에 순서가 변경되면 테스트가 실패한다. - 0과 같은 매직넘버가 발생한다.
이로인해 코드의 가독성이 점점 떨어져가고 유지보수하기 어려운 코드가 되어가는 느낌을 받았다.
위의 코드는 list의 첫번 째 값이 무엇인지 테스트하는 코드이다.
AssertJ
에서 제공하는 다양한 api를 통해 List
를 효과적으로 테스트할 수 있다.
contain
컬렉션 안에 해당 값이 포함 되어 있는지를 검사하는 기능을 제공한다.
@Test
@DisplayName("List 테스트 - contain")
void test20230629131425() {
List<String> testList = Arrays.asList("test1", "test2", "test3");
// test1이 포함되어 있나
assertThat(testList).contains("test1");
// 순서가 정확해야함
assertThat(testList).containsExactly("test1", "test2", "test3");
// 순서는 정확하지 않아도됨
assertThat(testList).containsExactlyInAnyOrder("test1", "test3", "test2");
}
객체를 가지고 있는 List 테스트하기
객체를 가지고 있는 List
를 테스트해보자.
public class User {
private final String name;
private final String address;
public User(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
}
간단한 유저 클래스를 선언한다.
객체안의 필드를 테스트하기 위해 extracting
메서드를 사용한다.
@Test
@DisplayName("List 테스트 - 객체")
void test20230629131426() {
List<User> testUsers = Arrays.asList(
new User("test1", "인천"),
new User("test2", "서울"),
new User("test3", "강원도")
);
assertThat(testUsers)
.extracting("address")
.contains("인천", "서울", "강원도");
assertThat(testUsers)
.extracting("address")
.containsExactlyInAnyOrder("인천", "강원도", "서울");
assertThat(testUsers)
.extracting(User::getAddress)
.containsExactlyInAnyOrder("인천", "강원도", "서울");
}
앞서 살펴본 contains
메서드와 함께 사용할 수 있다.
extracting
에서는 메서드 레퍼런스가 가능하다.
조금 더 복잡한 객체를 담은 List
를 테스트해보자.
public class User {
private final String name;
private final Address address;
public User(String name, String address) {
this.name = name;
this.address = new Address(address);
}
public String getName() {
return name;
}
public Address getAddress() {
return address;
}
}
public class Address {
private final String city;
public Address(String city) {
this.city = city;
}
public String getCity() {
return city;
}
}
테스트를 위한 클래스를 선언한다.
User
클래스가 Address
클래스를 포함하는 관계이다.
각각의 유저 인스턴스 안에 있는 주소를 테스트하는 코드를 작성하면 다음과 같다.
@Test
@DisplayName("List 테스트 - 복잡한 객체")
void test20230629131427() {
List<User> testUsers = Arrays.asList(
new User("test1", "인천"),
new User("test2", "서울"),
new User("test3", "강원도")
);
assertThat(testUsers)
.extracting("address")
.extracting("city")
.contains("인천", "서울", "강원도");
assertThat(testUsers)
.extracting(User::getAddress)
.extracting(Address::getCity)
.contains("인천", "서울", "강원도");
assertThat(testUsers)
.extracting("address.city")
.contains("인천", "서울", "강원도");
}
이렇게 List
를 테스트하는 코드들을 알아봤다.
List
를 다룰 일이 많은데 위의 방법으로 좀 더 견고하게 테스트할 수 있을 것 같다.
더 좋은 방법이 있다면 댓글로 남겨주시길..ㅎ
반응형