Skip to content

Commit

Permalink
setting: Controller 테스트 코드 작성을 위한 환경 세팅 (#35)
Browse files Browse the repository at this point in the history
* test: Controller 테스트 코드 작성을 위해 필요한 코드 추가

* test: AdminController 테스트 코드 작성

* fix: JpaAuditing 관련 config Application 실행 코드로부터 분리

* feat: Application의 timezone을 Asia/Seoul로 설정

* fix: Spring Rest Docs 관련 코드 제거

* fix: Jib 빌드 시 테스트 코드 무시 명령 제거
  • Loading branch information
leeeeeyeon authored Jan 17, 2024
1 parent c03ad80 commit 0d4b9ce
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/packy-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
uses: gradle/gradle-build-action@v2

- name: Build with Gradle
run: ./gradlew -Pdev clean jib -x test
run: ./gradlew -Pdev clean jib

- name: Get current time
uses: 1466587594/get-current-time@v2
Expand Down
7 changes: 4 additions & 3 deletions packy-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ dependencies {
// oauth
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'

// jwt
compileOnly group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.2'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.2'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.2'
implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.2'
implementation group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.2'
implementation group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.2'

// webflux (for WebClient)
implementation 'org.springframework.boot:spring-boot-starter-webflux'
Expand Down
11 changes: 9 additions & 2 deletions packy-api/src/main/java/com/dilly/ApiApplication.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package com.dilly;

import java.util.TimeZone;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

import jakarta.annotation.PostConstruct;

@SpringBootApplication
@EnableJpaAuditing
public class ApiApplication {

@PostConstruct
public void init() {
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"));
}

public static void main(String[] args) {
System.setProperty("spring.config.name", "application-api, application-domain");
SpringApplication.run(ApiApplication.class, args);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.dilly.global.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@Configuration
@EnableJpaAuditing
public class JpaAuditingConfig {
}
12 changes: 12 additions & 0 deletions packy-api/src/test/java/com/dilly/ApiApplicationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.dilly;

import org.junit.jupiter.api.Test;
import org.springframework.test.context.ActiveProfiles;

@ActiveProfiles("test")
class ApiApplicationTest {

@Test
void contextLoads() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.dilly.admin.api;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import com.dilly.global.ControllerTestSupport;
import com.dilly.global.WithCustomMockUser;

class AdminControllerTest extends ControllerTestSupport {

@DisplayName("서버 상태를 확인한다.")
@Test
@WithCustomMockUser
void healthCheck() throws Exception {
// given // when // then
// TODO: active profile이 null로 뜸
mockMvc.perform(
get("/api/v1/admin/health")
)
.andDo(print())
.andExpect(status().isOk());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.dilly.global;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;

import com.dilly.admin.api.AdminController;
import com.dilly.admin.application.AdminService;
import com.fasterxml.jackson.databind.ObjectMapper;

@WebMvcTest(
controllers = {
AdminController.class
}
)
public abstract class ControllerTestSupport {
static {
System.setProperty("spring.config.name", "application-test");
}

@Autowired
protected MockMvc mockMvc;

@Autowired
protected ObjectMapper objectMapper;

@MockBean
protected AdminService adminService;
}
13 changes: 13 additions & 0 deletions packy-api/src/test/java/com/dilly/global/WithCustomMockUser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.dilly.global;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import org.springframework.security.test.context.support.WithSecurityContext;

@Retention(RetentionPolicy.RUNTIME)
@WithSecurityContext(factory = WithCustomMockUserSecurityContextFactory.class)
public @interface WithCustomMockUser {

String id() default "1";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.dilly.global;

import java.security.Key;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.test.context.support.WithSecurityContextFactory;
import org.springframework.test.context.ActiveProfiles;

import com.dilly.member.Role;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;

@ActiveProfiles("test")
public class WithCustomMockUserSecurityContextFactory implements WithSecurityContextFactory<WithCustomMockUser> {

@Value("${jwt.secret}")
String secretKey;

@Override
public SecurityContext createSecurityContext(WithCustomMockUser annotation) {
final SecurityContext securityContext = SecurityContextHolder.createEmptyContext();

Claims claims;
UserDetails principal;
Collection<? extends GrantedAuthority> authorities;

long now = (new Date()).getTime();
long acessTokenExpireTime = 1000 * 60 * 30;
Date accessTokenExpiresIn = new Date(now + acessTokenExpireTime);

byte[] keyBytes = Decoders.BASE64.decode(secretKey);
Key key = Keys.hmacShaKeyFor(keyBytes);

String accessToken = Jwts.builder()
.setSubject(annotation.id())
.claim("provider", "KAKAO")
.claim("nickname", "테스트")
.claim("auth", Role.ROLE_USER)
.setExpiration(accessTokenExpiresIn) // 토큰 만료 시간 설정
.signWith(key, SignatureAlgorithm.HS512)
.compact(); // 토큰 생성

claims = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(accessToken)
.getBody();
authorities = Arrays.stream(claims.get("auth").toString().split(","))
.map(SimpleGrantedAuthority::new)
.toList();
principal = new User(claims.getSubject(), "", authorities);

final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
principal, "", authorities
);
securityContext.setAuthentication(authenticationToken);
return securityContext;

}
}
2 changes: 2 additions & 0 deletions packy-api/src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
jwt:
secret: 'testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest'

0 comments on commit 0d4b9ce

Please sign in to comment.