tools & libs/단위테스트(junit, spock)

[spring test] 3. @Service Layer test

  • -

이번에는 service 영역에 대한 테스트를 처리해보자.

 

@Service Layer Test

 

@Service Layer

@Service Layer는 통상 @Repository에 의존한다. 즉 @Repository가 없으면 컴파일조차 할 수가 없다.

@Service
@RequiredArgsConstructor
public class BoardService {
    private final BoardRepository repo;

    public Board write(Board board) {
        return repo.save(board);
    }

    public Optional<Board> select(long boardNo) {
        return repo.findById(boardNo);
    }
}

 

하지만 @Service에 대한 테스트는 @Repository에 대한 테스트가 아니기 때문에 진짜 @Repository가 필요하지는 않고 완벽하게 동작하는 @Repository가 존재한다고 생각하고 진행한다. 이 완벽하게 동작하는 @Repository를 만들기 위해서 가짜 객체인 Mock을 사용한다.

Mock을 만들 때 Junit에서 직접 MockitoExtension을 확장하는 방식SpringBootTest에서 사용하는 방식이 가능하다.

JUnit을 이용하는 방법은 다음을 참조하자.

 

[junit] jupiter 4. 가짜 객체를 활용한 테스트

가짜 객체를 이용한 테스팅 프로젝트를 진행하다 보면 진짜 객체를 사용하지 못하거나 하지 말아야 할 경우가 왕왕 발생한다. 예를 들어 Service가 Repository를 호출하는 구조에서 Service는 만들어졌

goodteacher.tistory.com

 

@SpringBootTest

일단 @SpringBootTest는 기본적으로 통합 테스트이다. 따라서 필요한 빈만 로딩하는 방법이 필요하다. @SpringBootTest는 classes 속성을 갖는데 여기에 클래스를 지정하면 해당 빈만을 로딩하고 생략하는 경우 전체 환경을 로딩한다.

다음으로 JUnit에서 제공되는 애너테이션에 대응하는 Spring의 애너테이션들을 살펴보자. 애너테이션이 살짝 달라질 뿐 개념, 사용법은 동일하다.

  Junit SpringBoot
Mock 생성 org.mockito.Mock org.springframework.boot.test.mock.mockito.MockBean
Spy 생성 org.mockito.Spy org.springframework.boot.test.mock.mockito.SpyBean
Mock 주입 org.mockito.InjectMocks @Autowired에서 자동 연결

 

@SpringBootTest(classes = BoardService.class) // 필요한 빈(테스트 대상)만 로딩
public class T_9312_TestMockAndSpyBean2 {
    
    @MockBean
    BoardRepository repo;    // 존재하지 않는 녀석을 새로 구성
    
    @Autowired
    BoardService service;
    private Board board;
    
    @BeforeEach
    public void setup() {
        board = Board.builder().boardNo(1L).writer("hong").content("sample").build();
    }
    
    @Test
    public void saveTest() {
        // given - 조건 및 setup
        when(repo.save(board)).thenReturn(board);
        // when - 테스트 하려는 행동
        Board result = service.write(board);
        // then - 결과 검증
        assertEquals(result, board);
    }
    
    @Test
    public void selectTest() {
        // given - 조건 및 setup
        when(repo.findById(2L)).thenReturn(Optional.empty());
        when(repo.findById(1L)).thenReturn(Optional.of(board));
        // when - 테스트 하려는 행동
        Optional<Board> result = service.select(2L);
        // then - 결과 검증
        assertTrue(result.isEmpty());
        
        // when
        result = service.select(1L);
        assertEquals(result.get(), board);
    }
}

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.