(spring)테스트 코드 맛보기

전성영·2022년 8월 3일
0

spring

목록 보기
26/31

프로젝트를 진행하면서 테스트 코드를 일부 작성해봤다. 나머지는 팀원 한 분이 맡아서 하셨다.
service 쪽 테스트 코드를 짜봤는데 맞는지 아닌지도 잘 모르겠고, controller 테스트 코드도 있는 것을 안 후로 공부를 조금 해보았다.

@WebMvcTest 를 사용한 이유는 @SpringBootTest 를 사용하면 실제 어플리케이션 설정을 모두 로드하기 때문에 어플리케이션 규모가 커지면 느려지기 때문이다.

build.gradle 에서 확인을 해주자! test할 때 필요하다.

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
tasks.named('test') {
    useJUnitPlatform()
}
or 이거 두 개의 차이는 찾아봐야 한다.
test {
    useJUnitPlatform()
}

MVC 테스트

먼저 MVC 패키지 안에 가짜 사용자를 만들어 줘야 한다.

MockSpringSecurityFilter

public class MockSpringSecurityFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {}

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        SecurityContextHolder.getContext()
                .setAuthentication((Authentication) ((HttpServletRequest) req).getUserPrincipal());
        chain.doFilter(req, res);
    }

    @Override
    public void destroy() {
        SecurityContextHolder.clearContext();
    }
}

그 후 테스트 하고싶은 곳에 간다.

TodoController

TodoController를 테스트하고 SecurityConfig를 excludeFilters 로 제외시킨다.

그리고 @MockBean을 이용하여 가짜 Bean을 등록시켜준다.

Spring에서 제공해주는 MockMvc 와 Principal도 선언해준다.

ObjectMapper를 통해 Object 형태로 변환을 해줄 수 있고,

WebApplicationContext를 통해 MockMvc를 빌드하게 된다.

mockUserSetup()은 로그인 처리를 해주는 것이다.
이를 위해 MockSpringSecurityFilter 해주고, 모듈도 추가한 것이다.

매 테스트 케이스 마다 this.mockUserSetup(); 가 들어간다.

UsernamePasswordAuthenticationToken 안에 UserDetailsImpl이 있었고 그 안에 User가 있다.
최종적으로 만들어진 것을 mockPrincipal 보낼 때 담아서 보내준다.

필터에 대해 좀 더 자세한 Reference - 여기

setup()은 MockSpringSecurityFilter 사용해서 세팅하는데,
SpringSecurity에 가짜 사용자 정보를 넣어주기 위해 Filter 사용해서 Authentication 하는 것이다.


이제 본격적으로 test 코드로 들어가보자!!

먼저 위에서 만들었던 mockUserSetup()을 통해 로그인 처리를 해준다.
그 후 Dto 데이터 형식에 맞춰서 데이터를 집어 넣는다.

objectMapper를 통해 Object 형식으로 변환을 해준다.

/api/todos로 요청을 보내고, json 형태를 담은 string 변수를 content에 넣는다.(HTTP Body 부분)
.contentType으로 type을 맞춰주고 .accept를 통하여 Json으로 받을 수 있다고 서버에게 알려준다.
.andExpect를 통해 응답값이 200 나오면 정상인 것이다.

그 후 verify 를 통해 검증을 해준다.
안에 인자를 보면 해당 api에서 사용한 service를 적어준 후, 메소드 명도 적어준다.
그 후 들어가는 파라미터에 맞게 적어주면 되는데
만약 인자가 Long 타입이면 anyLong()을 적어주면 된다!


추가 사진

api에 파라미터가 들어가있는 경우에는 , [숫자] 를 적어주면 된다.
response 값이 없다면 content, contenttype, accept는 생략이다!




이제 service 쪽 코드도 보자!

TodoService

Mockito에서 제공하는 목 객체를 사용하기 위해 @ExtendWith(MockitoExtension.class) 를 달아준다.

그 후 @Mock, @Spy와 @InjectMock을 통하여 Mock 객체를 만들어준다.

@Mock - 빈 껍데기, @Spy - 모든 기능을 가지는 완전한 객체

Spring Boot Container가 테스트 시에 필요하고, Bean이 Container에 존재한다면 @MockBean을 사용하고 아닌 경우에는 @Mock을 사용한다는 데 아직 구별을 잘 못하겠다,,

셋업에 필요한 변수들과 생성자를 생성해준다 쭉!!!


setUp()에서 테스트 코드 실행 전 들어가야 할 내용들을 설정해준다.

todoService = new TodoService( );

안에는 todoService에서 사용하는 bean 객체들을 넣어주면 된다.



todoRegisterDto 데이터 형식에 맞춰 넣어준다. 그 후 service단에 있는 메소드를 실행시킨 결과를 result에 담고 assertEquals로 비교해준다.

만약 실패 testcase를 넣고 싶다면?

//when
CustomException exception = Assertions.assertThrows(CustomException.class,
        () -> todoService.registerTodo(todoRegisterDto, userDetails));

//then
Assertions.assertEquals("친구와 먼저 매칭을 먼저 해주세요."
,exception.getErrorCode().getMessage());

이런식으로 해주면 된다!


다음은 given 이다. todoRepository에 있는 findById가 실행되었을 때 기댓값을 뒤에 willReturn에 넣어주면 된다.
given 안에 들어있는 두 매소드는 confirmTodo에 있다.

탑건 4dx로 보고싶다 탑건

profile
Slow and Steady

0개의 댓글