TIL - QueryDSL private access 오류 | Spring Security 에서 Controller 테스트 코드 작성 오류

su·2023년 7월 31일
0

TIL

목록 보기
54/93
post-thumbnail

문제 - QueryDSL 오류

1) 문제

QueryDsl을 사용하고자, gradle에서 의존성을 추가해주었다.
그리고 Repository에서는 QuerydslPredicateExecutor<Entity명> 를 추가해주었다.
코드를 확인하고 실행을 누른 순간 ..!

Type has private access in 'Entity명'
public final EnumPath<Entity.Type> type = createEnum("type", Entity.Type.class);

오류가 발생했다...
해당 엔티티 클래스 내의 Type에 접근할 수가 없다고 한다 ..!
Enum.Type에 접근해야 QueryDSL 파일을 만들 수 있는 것 같다 ..

2) 시도

Entity 클래스 파일을 다시 읽어보았다.
내가 Type으로 정의해두었던 Enum 필드가 private으로 선언되어 있었다.
하지만 Entity 내의 정의해둔 필드들은 다 private으로 선언하는데,
왜 Enum으로 정의한 필드만 오류가 나는거지 ..?

@Enumerated(EnumType.STRING)
private Type type;

private enum Type {
	PUBLIC, PRIVATE;
}

3) 해결

아주 끔찍한 실수를 했다. 정답은 필드의 접근제어자가 아니었다 ..
enum 타입 자체를 private으로 주어버렸다..!

@Enumerated(EnumType.STRING)
private Type type;

public enum Type {
	PUBLIC, PRIVATE;
}

enum Type 자체를 private으로 선언한 실수였ㄷㅏ ..
Entity의 필드는 private으로 선언해주는 것이 맞고,
enum으로 정의한 Type은 public으로 선언했어야 했다.

4) 배운 점

QueryDSL을 사용할 때, 해당 Entity 내의 필드는 private으로 선언해도 상관없지만,
해당 필드가 enum 타입을 갖는다면, 그 enum 파일은 public으로 선언해야 QueryDSL을 사용할 수 있다 !

문제 - 테스트 코드 작성하기

1) 문제

Controller를 테스트 하는 코드를 작성하려고 했다.
예시가 있어서 그대로 따라해봤지만 .. 실패 ! ㅎㅎ
내가 요청한 것은 200 상태코드인데, 자꾸 400 혹은, 403 혹은, 404 상태코드가 나타났다.

java.lang.AssertionError: Status expected:<200> but was:<400>

비슷한 형태의 오류만 반복해서 보다가, 테스트 코드를 다시 작성해보기로 했다.

2) 시도

Spring Security가 적용되어서 Filter가 있는 상태의 Controller 테스트 코드를 작성한 사례를 찾아봤다.

.with() 를 사용하는 경우도 있었고,
@WithMockUser()라는 에너테이션을 직접 생성해서 사용하는 경우가 있었다.

.with(SecurityMockMvcRequestPostProcessors.user(user))

해당 코드를 사용해보고자 했다.
.user(user)에서 안에 들어가는 user는 UserDetails 타입이다!
이미 회원 정보가 존재하기 때문에, 존재하는 회원으로 UserDetails를 생성하는 setUp() 테스트 메소드를 작성하고, @BeforeEach 에너테이션을 붙였다.
그리고 POST 테스트 코드를 작성해서 다시 테스트 해봤지만 ..? 실패했다 ..

<출처>

3) 해결

원래는 로그인을 하고 나면, JWT를 생성해서 Response Header에 담아주었다 !
그 과정을 생략한 채로 테스트를 진행하려고 하다 보니, 인가 부분에서 오류가 발생했던 듯 하다.

JwtUtil 클래스에서 createToken을 이용해서 토큰을 만들어주기 때문에
JwtUtil을 @Autowired 해주고, JwtUtil에서 토큰을 만들어주는 메소드를 사용해서 token을 생성해준다.
그리고 mockmvc에 with(token)을 해준다 !
그러면 원하는대로 header에 token을 추가해주게 된다.

4) 배운 점

지난주부터 고민하던 테스트 코드를 해결해서 일단 기분이 정말 좋다.. ㅎㅎ
기본적으로 내가 설정해둔 로그인은, Filter 단에서 인증을 거친 다음에 Header에 JWT를 담아서 클라이언트로 반환한다.
그리고 그 JWT를 클라이언트로부터 받아 인가를 진행하기 때문에, Header에 JWT가 없으면 Controller에 접근이 되지 않는 것이다 !

profile
(❁´◡`❁)

1개의 댓글

comment-user-thumbnail
2023년 7월 31일

좋은 정보 감사합니다

답글 달기