반응형
그니_
삽질탐방기
그니_
  • 분류 전체보기 (24)
    • 개발 (15)
    • ETC (1)
    • 트러블슈팅 & 삽질기록 (7)
    • 성능개선 (1)

인기 글

최근 글

최근 댓글

태그

  • chatgpt 정리
  • chatgpt 기록 삭제
  • chatgpt 확장 프로그램
  • spring docker
  • easyrandom
  • timeunit
  • java
  • spring docker compose
  • 마이크로소프트 ai tour
  • GPT 플러그인
  • Database
  • chatgpt 채팅 삭제
  • spring log
  • Spring
  • chatgpt 히스토리 삭제
  • chatgpt 확장 추천
  • 네트워크
  • index
  • db
  • springboot
hELLO · Designed By 정상우.
그니_

삽질탐방기

개발

Easy Random을 활용한 Unit Test

2023. 3. 8. 01:36
반응형

테스트 데이터 구성하기에 용이한 Easy Radom 라이브러리에 대해 글을 써보고자 한다. 

 

본론으로 들어가기 앞서, 테스트 코드를 짜다보면 데이터를 구성하는게 생각보다 힘들다..(아니 귀찮다)

 

물론 각자마다 테스트용 데이터를 구성하는 방법도 여러가지겠지만 그것마저 귀찮다 싶을땐,

 

Easy Random이라는 library를 사용해보는 걸 추천한다! 현업에서도 팀원들에게 공유해 사용중인데 편하게 잘 쓰이고 있다.

 

본론으로 들어와 간단하게 테스트 코드를 위한 준비 및 사용을 위한 dependency 추가를 진행한다.

 

gradle 기준

testImplementation 'org.jeasy:easy-random-core:5.0.0'

maven 기준

<dependency>
    <groupId>org.jeasy</groupId>
    <artifactId>easy-random-core</artifactId>
    <version>5.0.0</version>
    <scope>test</scope>
</dependency>

 

example

전체 멤버를 조회시 5인 이상일시 정상 동작하는 코드가 있다고 가정을 해보자.

 

 

package com.example.demo;

import java.util.List;

public class ExampleService {
    private final ExampleRepository exampleRepository;

    public ExampleService(ExampleRepository exampleRepository) {
        this.exampleRepository = exampleRepository;
    }

    public List<Member> getMemberList() {
        List<Member> memberList = exampleRepository.findAll();
        if(memberList.size() < 5) {
            throw new RuntimeException("가입한 멤버수가 5인 이하네요.. 분발하세요");
        }
        return memberList;
    }
}
package com.example.demo;

import java.util.List;

public interface ExampleRepository {
    List<Member> findAll();
}
package com.example.demo;

import lombok.Data;
import lombok.Getter;

import java.time.LocalDate;

@Data
public class Member {
    private String name;
    private int age;
    private boolean isAdult;
    private Gender gender;
    private LocalDate birthday;

    @Getter
    enum Gender {
        MALE,
        FEMALE
    }
}

 

UnitTest

package com.example.demo;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

@ExtendWith(MockitoExtension.class)
class ExampleServiceTest {

    @Mock
    ExampleRepository exampleRepository;

    @InjectMocks
    ExampleService exampleService;

    @DisplayName("전체멤버 조회시 5인 이상이면 통과")
    @Test
    void getMemberList() {
        //given
        List<Member> memberList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Member member = new Member();
            member.setName("테스터" + i);
            member.setAge(4 * i);
            member.setBirthday(LocalDate.now().minusYears((long)i));
            member.setAdult(true);
            member.setGender(Member.Gender.MALE);
            memberList.add(member);
        }
        given(exampleRepository.findAll()).willReturn(memberList);

        //when
        List<Member> result = exampleService.getMemberList();

        //then
        assertThat(result.size()).isEqualTo(5);
        verify(exampleRepository, times(1)).findAll();
        result.forEach(System.out::println);
    }
}

 

위의 예제처럼 Mocking하기 위해 직접 구성하거나 여러건은 loop를 활용해 데이터 구성하는 경우가 생각보다 많다.

 

그런데 Easy Random을 활용하면???

 

UnitTest

package com.example.demo;

import org.jeasy.random.EasyRandom;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

@ExtendWith(MockitoExtension.class)
class ExampleServiceTest {

    @Mock
    ExampleRepository exampleRepository;

    @InjectMocks
    ExampleService exampleService;

    @DisplayName("Easy Random으로 구성된 멤버조회")
    @Test
    void getMemberListByEasyRandom() {
        //given
        EasyRandom easyRandom = new EasyRandom();
        List<Member> memberList = easyRandom.objects(Member.class, 5)
                .collect(Collectors.toList());
        given(exampleRepository.findAll()).willReturn(memberList);

        //when
        List<Member> result = exampleService.getMemberList();

        //then
        assertThat(result.size()).isEqualTo(5);
        verify(exampleRepository, times(1)).findAll();
        result.forEach(System.out::println);
    }
}

 

적용 후 코드를 살펴보면 이전과는 다르게 for loop 및 값 주입이 사라지니 코드라인도 줄고 깔끔한 느낌을 준다.

 

사용법은 간단하다,

EasyRandom 객체 생성 후 objects() 혹은 nextObjects() 메소드를 호출해 주입할 Type, size를 넣어주면 그에 해당하는 타입의 사이즈만큼 값이 생성된다.

 

결과값은 아래와 같다.

 

어떤식으로 필드의 타입을 추론해 값을 주입을 해주는지 궁금하여 EasyRandom 구현체 내부 코드를 따라가보니,리플렉션 기반으로 필드의 타입에 따라 각각 context를 생성해주는 방식으로 돌아가는 코드였다. 

 

 

+ 추가로 각각 필드의 셋팅값 range 지정등을 위해서라면 RandomizerProvider interface 구현체를 이용해 커스텀할수 있는것도 제공해 주는걸로 보인다.

 

 

글재주가 없어서 잘 전달이 됐을진 모르겠지만, 공유차 적었는데 도움이 됐으면 싶다~~~~~

 

참고 

https://github.com/j-easy/easy-random

반응형
저작자표시 (새창열림)

'개발' 카테고리의 다른 글

[spring] OpenFeign 로그 사용자화  (0) 2023.08.30
spring-boot docker-compose 사용법  (1) 2023.05.14
[후기] NHN forward 2022  (0) 2022.11.26
서비스형 재해복구  (0) 2022.10.25
flyway를 이용한 db migration  (0) 2022.10.05
    '개발' 카테고리의 다른 글
    • [spring] OpenFeign 로그 사용자화
    • spring-boot docker-compose 사용법
    • [후기] NHN forward 2022
    • 서비스형 재해복구
    그니_
    그니_
    머리속에서만 존재하는 내용을 글로 정리

    티스토리툴바