add testcode

This commit is contained in:
ondal 2025-02-14 23:54:34 +09:00
parent 2f672a8ea5
commit 17d8591ae9
107 changed files with 7513 additions and 36 deletions

Binary file not shown.

Binary file not shown.

1
.idea/modules.xml generated
View File

@ -4,6 +4,7 @@
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/common/lifesub.common.main.iml" filepath="$PROJECT_DIR$/.idea/modules/common/lifesub.common.main.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/common/lifesub.common.main.iml" filepath="$PROJECT_DIR$/.idea/modules/common/lifesub.common.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/member/lifesub.member.main.iml" filepath="$PROJECT_DIR$/.idea/modules/member/lifesub.member.main.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/member/lifesub.member.main.iml" filepath="$PROJECT_DIR$/.idea/modules/member/lifesub.member.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/member/lifesub.member.test.iml" filepath="$PROJECT_DIR$/.idea/modules/member/lifesub.member.test.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/mysub-biz/lifesub.mysub-biz.main.iml" filepath="$PROJECT_DIR$/.idea/modules/mysub-biz/lifesub.mysub-biz.main.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/mysub-biz/lifesub.mysub-biz.main.iml" filepath="$PROJECT_DIR$/.idea/modules/mysub-biz/lifesub.mysub-biz.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/mysub-infra/lifesub.mysub-infra.main.iml" filepath="$PROJECT_DIR$/.idea/modules/mysub-infra/lifesub.mysub-infra.main.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/mysub-infra/lifesub.mysub-infra.main.iml" filepath="$PROJECT_DIR$/.idea/modules/mysub-infra/lifesub.mysub-infra.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/recommend/lifesub.recommend.main.iml" filepath="$PROJECT_DIR$/.idea/modules/recommend/lifesub.recommend.main.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/recommend/lifesub.recommend.main.iml" filepath="$PROJECT_DIR$/.idea/modules/recommend/lifesub.recommend.main.iml" />

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$/../../../member/build/generated/sources/annotationProcessor/java/test">
<sourceFolder url="file://$MODULE_DIR$/../../../member/build/generated/sources/annotationProcessor/java/test" isTestSource="true" generated="true" />
</content>
</component>
</module>

View File

@ -80,8 +80,12 @@ configure(subprojects.findAll { !it.name.endsWith('-biz') && it.name != 'common'
// Swagger // Swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0'
//-- spring security test
testImplementation 'org.springframework.security:spring-security-test'
// Test Containers // Test Containers
testImplementation 'org.testcontainers:postgresql' testImplementation 'org.testcontainers:postgresql'
testImplementation 'org.testcontainers:junit-jupiter'
// WebFlux for WebMvc Testing // WebFlux for WebMvc Testing
implementation 'org.springframework.boot:spring-boot-starter-webflux' implementation 'org.springframework.boot:spring-boot-starter-webflux'

Binary file not shown.

View File

@ -0,0 +1,151 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - MemberControllerIntegrationTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>MemberControllerIntegrationTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/com.unicorn.lifesub.member.test.integration.controller.html">com.unicorn.lifesub.member.test.integration.controller</a> &gt; MemberControllerIntegrationTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">4</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.781s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
<li>
<a href="#tab1">Standard output</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Method name</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">로그인 실패 테스트 - 잘못된 요청 형식</td>
<td class="success">loginFailInvalidRequest()</td>
<td class="success">0.110s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">로그인 성공 테스트</td>
<td class="success">loginSuccess()</td>
<td class="success">0.060s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">로그아웃 실패 테스트 - 잘못된 요청 형식</td>
<td class="success">logoutFailInvalidRequest()</td>
<td class="success">0.060s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">로그아웃 성공 테스트</td>
<td class="success">logoutSuccess()</td>
<td class="success">0.551s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
<div id="tab1" class="tab">
<h2>Standard output</h2>
<span class="code">
<pre>
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.0)
2025-02-14T23:45:39.822+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.c.MemberControllerIntegrationTest : Starting MemberControllerIntegrationTest using Java 18.0.2 with PID 99945 (started by ondal in /Users/ondal/home/workspace/lifesub/member)
2025-02-14T23:45:39.825+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] .m.t.i.c.MemberControllerIntegrationTest : Running with Spring Boot v3.4.0, Spring v6.2.0
2025-02-14T23:45:39.825+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.c.MemberControllerIntegrationTest : The following 1 profile is active: &quot;integration-test&quot;
2025-02-14T23:45:40.778+09:00 WARN 99945 --- [member-service-test] [ Test worker] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 6aa45464-02a7-4558-8a92-e66c40f4756b
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2025-02-14T23:45:40.793+09:00 INFO 99945 --- [member-service-test] [ Test worker] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
2025-02-14T23:45:42.817+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring TestDispatcherServlet ''
2025-02-14T23:45:42.821+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
2025-02-14T23:45:42.830+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 5 ms
2025-02-14T23:45:42.954+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.c.MemberControllerIntegrationTest : Started MemberControllerIntegrationTest in 3.343 seconds (process running for 65.774)
2025-02-14T23:45:43.628+09:00 WARN 99945 --- [member-service-test] [ Test worker] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity&lt;com.unicorn.lifesub.common.dto.ApiResponse&lt;com.unicorn.lifesub.common.dto.JwtTokenDTO&gt;&gt; com.unicorn.lifesub.member.controller.MemberController.login(com.unicorn.lifesub.member.dto.LoginRequest) with 2 errors: [Field error in object 'loginRequest' on field 'password': rejected value [null]; codes [NotBlank.loginRequest.password,NotBlank.password,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [loginRequest.password,password]; arguments []; default message [password]]; default message [비밀번호는 필수입니다.]] [Field error in object 'loginRequest' on field 'userId': rejected value [null]; codes [NotBlank.loginRequest.userId,NotBlank.userId,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [loginRequest.userId,userId]; arguments []; default message [userId]]; default message [사용자 ID는 필수입니다.]] ]
2025-02-14T23:45:43.705+09:00 WARN 99945 --- [member-service-test] [ Test worker] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity&lt;com.unicorn.lifesub.common.dto.ApiResponse&lt;com.unicorn.lifesub.member.dto.LogoutResponse&gt;&gt; com.unicorn.lifesub.member.controller.MemberController.logout(com.unicorn.lifesub.member.dto.LogoutRequest): [Field error in object 'logoutRequest' on field 'userId': rejected value [null]; codes [NotBlank.logoutRequest.userId,NotBlank.userId,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [logoutRequest.userId,userId]; arguments []; default message [userId]]; default message [사용자 ID는 필수입니다.]] ]
</pre>
</span>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,526 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - MemberRepositoryIntegrationTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>MemberRepositoryIntegrationTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/com.unicorn.lifesub.member.test.integration.repository.html">com.unicorn.lifesub.member.test.integration.repository</a> &gt; MemberRepositoryIntegrationTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">4</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.625s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
<li>
<a href="#tab1">Standard output</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Method name</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">회원 삭제 테스트</td>
<td class="success">givenExistingMember_whenDelete_thenCannotFind()</td>
<td class="success">0.081s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">회원 정보 업데이트 테스트</td>
<td class="success">givenExistingMember_whenUpdateInfo_thenSuccess()</td>
<td class="success">0.178s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">회원 저장 및 조회 테스트</td>
<td class="success">givenMemberEntity_whenSave_thenFindByUserId()</td>
<td class="success">0.341s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">존재하지 않는 회원 조회 테스트</td>
<td class="success">givenNonExistentUserId_whenFindByUserId_thenReturnEmpty()</td>
<td class="success">0.025s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
<div id="tab1" class="tab">
<h2>Standard output</h2>
<span class="code">
<pre>2025-02-14T23:45:43.930+09:00 INFO 99945 --- [member-service-test] [ Test worker] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest]: MemberRepositoryIntegrationTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2025-02-14T23:45:44.293+09:00 INFO 99945 --- [member-service-test] [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.unicorn.lifesub.member.MemberApplication for test class com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest
2025-02-14T23:45:44.315+09:00 INFO 99945 --- [member-service-test] [ Test worker] tc.postgres:13.2-alpine : Creating container for image: postgres:13.2-alpine
2025-02-14T23:45:44.451+09:00 INFO 99945 --- [member-service-test] [ Test worker] tc.postgres:13.2-alpine : Container postgres:13.2-alpine is starting: 6b79d075221360d24585825bd669f3f2099a36a70cc40b3b166e8fb6762cc3e9
2025-02-14T23:45:46.654+09:00 INFO 99945 --- [member-service-test] [ Test worker] tc.postgres:13.2-alpine : Container postgres:13.2-alpine started in PT2.338311S
2025-02-14T23:45:46.673+09:00 INFO 99945 --- [member-service-test] [ Test worker] tc.postgres:13.2-alpine : Container is started (JDBC URL: jdbc:postgresql://localhost:58666/member?loggerLevel=OFF)
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.0)
2025-02-14T23:45:47.048+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.r.MemberRepositoryIntegrationTest : Starting MemberRepositoryIntegrationTest using Java 18.0.2 with PID 99945 (started by ondal in /Users/ondal/home/workspace/lifesub/member)
2025-02-14T23:45:47.050+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] .m.t.i.r.MemberRepositoryIntegrationTest : Running with Spring Boot v3.4.0, Spring v6.2.0
2025-02-14T23:45:47.058+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.r.MemberRepositoryIntegrationTest : The following 1 profile is active: &quot;integration-test&quot;
2025-02-14T23:45:48.793+09:00 INFO 99945 --- [member-service-test] [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-02-14T23:45:48.950+09:00 INFO 99945 --- [member-service-test] [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 107 ms. Found 1 JPA repository interface.
2025-02-14T23:45:49.932+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2025-02-14T23:45:49.958+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled
2025-02-14T23:45:50.150+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
2025-02-14T23:45:50.161+09:00 INFO 99945 --- [member-service-test] [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Starting...
2025-02-14T23:45:50.266+09:00 INFO 99945 --- [member-service-test] [ Test worker] com.zaxxer.hikari.pool.HikariPool : HikariPool-2 - Added connection org.postgresql.jdbc.PgConnection@54210bb8
2025-02-14T23:45:50.272+09:00 INFO 99945 --- [member-service-test] [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Start completed.
2025-02-14T23:45:50.290+09:00 WARN 99945 --- [member-service-test] [ Test worker] org.hibernate.orm.deprecation : HHH90000025: PostgreSQLDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
2025-02-14T23:45:50.300+09:00 INFO 99945 --- [member-service-test] [ Test worker] org.hibernate.orm.connections.pooling : HHH10001005: Database info:
Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-2)']
Database driver: undefined/unknown
Database version: 13.2
Autocommit mode: undefined/unknown
Isolation level: undefined/unknown
Minimum pool size: undefined/unknown
Maximum pool size: undefined/unknown
2025-02-14T23:45:50.938+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2025-02-14T23:45:51.157+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
create table member_roles (
user_id varchar(255) not null,
role varchar(255)
)
Hibernate:
create table member_roles (
user_id varchar(255) not null,
role varchar(255)
)
2025-02-14T23:45:51.193+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
create table members (
user_id varchar(255) not null,
created_at timestamp(6),
updated_at timestamp(6),
password varchar(255) not null,
user_name varchar(255) not null,
primary key (user_id)
)
Hibernate:
create table members (
user_id varchar(255) not null,
created_at timestamp(6),
updated_at timestamp(6),
password varchar(255) not null,
user_name varchar(255) not null,
primary key (user_id)
)
2025-02-14T23:45:51.224+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
alter table if exists member_roles
add constraint FKkrahbaoj05n0hyabejnnrmft
foreign key (user_id)
references members
Hibernate:
alter table if exists member_roles
add constraint FKkrahbaoj05n0hyabejnnrmft
foreign key (user_id)
references members
2025-02-14T23:45:51.242+09:00 INFO 99945 --- [member-service-test] [ Test worker] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-02-14T23:45:51.723+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.r.MemberRepositoryIntegrationTest : Started MemberRepositoryIntegrationTest in 5.01 seconds (process running for 74.544)
2025-02-14T23:45:51.942+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
2025-02-14T23:45:51.963+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
member_roles
(user_id, role)
values
(?, ?)
Hibernate:
insert
into
member_roles
(user_id, role)
values
(?, ?)
2025-02-14T23:45:52.003+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
2025-02-14T23:45:52.033+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
Hibernate:
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
2025-02-14T23:45:52.180+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
2025-02-14T23:45:52.188+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
member_roles
(user_id, role)
values
(?, ?)
Hibernate:
insert
into
member_roles
(user_id, role)
values
(?, ?)
2025-02-14T23:45:52.195+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
2025-02-14T23:45:52.203+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
Hibernate:
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
2025-02-14T23:45:52.284+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
update
members
set
created_at=?,
password=?,
updated_at=?,
user_name=?
where
user_id=?
Hibernate:
update
members
set
created_at=?,
password=?,
updated_at=?,
user_name=?
where
user_id=?
2025-02-14T23:45:52.312+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
2025-02-14T23:45:52.318+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
Hibernate:
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
2025-02-14T23:45:52.367+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
2025-02-14T23:45:52.394+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
2025-02-14T23:45:52.400+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
member_roles
(user_id, role)
values
(?, ?)
Hibernate:
insert
into
member_roles
(user_id, role)
values
(?, ?)
2025-02-14T23:45:52.404+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
2025-02-14T23:45:52.408+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
Hibernate:
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
2025-02-14T23:45:52.437+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
delete
from
member_roles
where
user_id=?
Hibernate:
delete
from
member_roles
where
user_id=?
2025-02-14T23:45:52.444+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
delete
from
members
where
user_id=?
Hibernate:
delete
from
members
where
user_id=?
2025-02-14T23:45:52.453+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
</pre>
</span>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - MemberServiceIntegrationTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>MemberServiceIntegrationTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/com.unicorn.lifesub.member.test.integration.service.html">com.unicorn.lifesub.member.test.integration.service</a> &gt; MemberServiceIntegrationTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">2</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">1.729s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Method name</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">로그아웃 처리 성공</td>
<td class="success">givenUserId_whenLogout_thenSuccess()</td>
<td class="success">1.518s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">유효한 자격증명으로 로그인 성공</td>
<td class="success">givenValidCredentials_whenLogin_thenReturnJwtToken()</td>
<td class="success">0.211s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -3,17 +3,17 @@
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/> <meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - CustomUserDetailsServiceTest</title> <title>Test results - CustomUserDetailsServiceUnitTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/> <link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/> <link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script> <script src="../js/report.js" type="text/javascript"></script>
</head> </head>
<body> <body>
<div id="content"> <div id="content">
<h1>CustomUserDetailsServiceTest</h1> <h1>CustomUserDetailsServiceUnitTest</h1>
<div class="breadcrumbs"> <div class="breadcrumbs">
<a href="../index.html">all</a> &gt; <a href="../index.html">all</a> &gt;
<a href="../packages/com.unicorn.lifesub.member.test.unit.config.jwt.html">com.unicorn.lifesub.member.test.unit.config.jwt</a> &gt; CustomUserDetailsServiceTest</div> <a href="../packages/com.unicorn.lifesub.member.test.unit.config.jwt.html">com.unicorn.lifesub.member.test.unit.config.jwt</a> &gt; CustomUserDetailsServiceUnitTest</div>
<div id="summary"> <div id="summary">
<table> <table>
<tr> <tr>
@ -41,7 +41,7 @@
</td> </td>
<td> <td>
<div class="infoBox" id="duration"> <div class="infoBox" id="duration">
<div class="counter">1.064s</div> <div class="counter">0.112s</div>
<p>duration</p> <p>duration</p>
</div> </div>
</td> </td>
@ -78,19 +78,19 @@
<tr> <tr>
<td class="success">givenExistingUserId_whenLoadUser_thenReturnUserDetails</td> <td class="success">givenExistingUserId_whenLoadUser_thenReturnUserDetails</td>
<td class="success">givenExistingUserId_whenLoadUser_thenReturnUserDetails()</td> <td class="success">givenExistingUserId_whenLoadUser_thenReturnUserDetails()</td>
<td class="success">0.008s</td> <td class="success">0.007s</td>
<td class="success">passed</td> <td class="success">passed</td>
</tr> </tr>
<tr> <tr>
<td class="success">givenNonExistentUserId_whenLoadUser_thenThrowException</td> <td class="success">givenNonExistentUserId_whenLoadUser_thenThrowException</td>
<td class="success">givenNonExistentUserId_whenLoadUser_thenThrowException()</td> <td class="success">givenNonExistentUserId_whenLoadUser_thenThrowException()</td>
<td class="success">0.864s</td> <td class="success">0.064s</td>
<td class="success">passed</td> <td class="success">passed</td>
</tr> </tr>
<tr> <tr>
<td class="success">givenUserWithRoles_whenLoadUser_thenMapAuthoritiesCorrectly</td> <td class="success">givenUserWithRoles_whenLoadUser_thenMapAuthoritiesCorrectly</td>
<td class="success">givenUserWithRoles_whenLoadUser_thenMapAuthoritiesCorrectly()</td> <td class="success">givenUserWithRoles_whenLoadUser_thenMapAuthoritiesCorrectly()</td>
<td class="success">0.192s</td> <td class="success">0.041s</td>
<td class="success">passed</td> <td class="success">passed</td>
</tr> </tr>
</table> </table>
@ -103,7 +103,7 @@
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/> <input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label> </label>
</div>Generated by </div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 4:50:22</p> <a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div> </div>
</div> </div>
</body> </body>

View File

@ -0,0 +1,228 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - JwtTokenProviderUnitTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>JwtTokenProviderUnitTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/com.unicorn.lifesub.member.test.unit.config.jwt.html">com.unicorn.lifesub.member.test.unit.config.jwt</a> &gt; JwtTokenProviderUnitTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">5</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.833s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
<li>
<a href="#tab1">Standard output</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Method name</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">givenInvalidToken_whenValidate_thenThrowException</td>
<td class="success">givenInvalidToken_whenValidate_thenThrowException()</td>
<td class="success">0.119s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">givenRequest_whenResolveToken_thenSuccess</td>
<td class="success">givenRequest_whenResolveToken_thenSuccess()</td>
<td class="success">0.673s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">givenToken_whenValidate_thenSuccess</td>
<td class="success">givenToken_whenValidate_thenSuccess()</td>
<td class="success">0.006s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">givenValidMember_whenCreateToken_thenSuccess</td>
<td class="success">givenValidMember_whenCreateToken_thenSuccess()</td>
<td class="success">0.028s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">givenValidToken_whenGetAuthentication_thenSuccess</td>
<td class="success">givenValidToken_whenGetAuthentication_thenSuccess()</td>
<td class="success">0.007s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
<div id="tab1" class="tab">
<h2>Standard output</h2>
<span class="code">
<pre>2025-02-14T23:45:55.728+09:00 INFO 99945 --- [member-service-test] [ Test worker] c.u.l.m.config.jwt.JwtTokenProvider : ******** validateToken: invalid-token
2025-02-14T23:45:55.759+09:00 ERROR 99945 --- [member-service-test] [ Test worker] c.u.l.m.config.jwt.JwtTokenProvider : Undefined Error: The token was expected to have 3 parts, but got 0.
com.auth0.jwt.exceptions.JWTDecodeException: The token was expected to have 3 parts, but got 0.
at com.auth0.jwt.TokenUtils.wrongNumberOfParts(TokenUtils.java:45) ~[java-jwt-4.4.0.jar:4.4.0]
at com.auth0.jwt.TokenUtils.splitToken(TokenUtils.java:23) ~[java-jwt-4.4.0.jar:4.4.0]
at com.auth0.jwt.JWTDecoder.&lt;init&gt;(JWTDecoder.java:37) ~[java-jwt-4.4.0.jar:4.4.0]
at com.auth0.jwt.JWTVerifier.verify(JWTVerifier.java:444) ~[java-jwt-4.4.0.jar:4.4.0]
at com.unicorn.lifesub.member.config.jwt.JwtTokenProvider.validateToken(JwtTokenProvider.java:112) ~[main/:na]
at com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest.lambda$givenInvalidToken_whenValidate_thenThrowException$0(JwtTokenProviderUnitTest.java:126) ~[test/:na]
at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:53) ~[junit-jupiter-api-5.11.3.jar:5.11.3]
at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:35) ~[junit-jupiter-api-5.11.3.jar:5.11.3]
at org.junit.jupiter.api.Assertions.assertThrows(Assertions.java:3128) ~[junit-jupiter-api-5.11.3.jar:5.11.3]
at com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest.givenInvalidToken_whenValidate_thenThrowException(JwtTokenProviderUnitTest.java:126) ~[test/:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:767) ~[junit-platform-commons-1.11.3.jar:1.11.3]
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$8(TestMethodTestDescriptor.java:217) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:156) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:160) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:160) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:119) ~[na:na]
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:94) ~[na:na]
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:89) ~[na:na]
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) ~[na:na]
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) ~[na:na]
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) ~[na:na]
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) ~[na:na]
at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source) ~[na:na]
at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) ~[na:na]
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) ~[na:na]
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) ~[na:na]
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) ~[na:na]
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) ~[na:na]
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113) ~[na:na]
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65) ~[na:na]
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) ~[gradle-worker.jar:na]
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) ~[gradle-worker.jar:na]
2025-02-14T23:45:55.832+09:00 INFO 99945 --- [member-service-test] [ Test worker] c.u.l.m.config.jwt.JwtTokenProvider : ******** validateToken: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0VXNlciIsInVzZXJJZCI6InRlc3RVc2VyIiwidXNlck5hbWUiOiJUZXN0IFVzZXIiLCJhdXRoIjpbIlJPTEVfVVNFUiJdLCJpYXQiOjE3Mzk1NDQzNTUsImV4cCI6MTc0MzE0NDM1NX0.mdBFO7WH3XMHafHC6WpEQ-j8D_uNHq8HnxubMgpfIhq6rkIOdOMO0w1iN0gskTyJOgxGAxe8P5LwynLSUO8jEQ
2025-02-14T23:45:55.859+09:00 INFO 99945 --- [member-service-test] [ Test worker] c.u.l.m.config.jwt.JwtTokenProvider : ******** validateToken: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0VXNlciIsImF1dGgiOlsiUk9MRV9VU0VSIl19.s0nwJ9sbCd7YYRCIj2yGgbuNP3KgpZ5SssKSOoo_FDg8mCrxilGVMaiv2gPGq0q0hx_RC413cAeMM-Y4nurEIw
</pre>
</span>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,116 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - MemberUnitTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>MemberUnitTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/com.unicorn.lifesub.member.test.unit.domain.html">com.unicorn.lifesub.member.test.unit.domain</a> &gt; MemberUnitTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">4</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.008s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Method name</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">givenMemberDomain_whenConvertToEntity_thenSuccess</td>
<td class="success">givenMemberDomain_whenConvertToEntity_thenSuccess()</td>
<td class="success">0.003s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">givenMemberEntity_whenConvertToDomain_thenSuccess</td>
<td class="success">givenMemberEntity_whenConvertToDomain_thenSuccess()</td>
<td class="success">0s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">givenMemberInfo_whenBuildMember_thenSuccess</td>
<td class="success">givenMemberInfo_whenBuildMember_thenSuccess()</td>
<td class="success">0.002s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">givenMultipleRoles_whenBuildMember_thenSuccess</td>
<td class="success">givenMultipleRoles_whenBuildMember_thenSuccess()</td>
<td class="success">0.003s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,116 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - MemberServiceImplUnitTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>MemberServiceImplUnitTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/com.unicorn.lifesub.member.test.unit.service.html">com.unicorn.lifesub.member.test.unit.service</a> &gt; MemberServiceImplUnitTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">4</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.055s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Method name</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">givenInvalidPassword_whenLogin_thenThrowException</td>
<td class="success">givenInvalidPassword_whenLogin_thenThrowException()</td>
<td class="success">0.017s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">givenLogoutRequest_whenLogout_thenSuccess</td>
<td class="success">givenLogoutRequest_whenLogout_thenSuccess()</td>
<td class="success">0.010s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">givenNonExistentUser_whenLogin_thenThrowException</td>
<td class="success">givenNonExistentUser_whenLogin_thenThrowException()</td>
<td class="success">0.008s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">givenValidCredentials_whenLogin_thenSuccess</td>
<td class="success">givenValidCredentials_whenLogin_thenSuccess()</td>
<td class="success">0.020s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -20,7 +20,7 @@
<tr> <tr>
<td> <td>
<div class="infoBox" id="tests"> <div class="infoBox" id="tests">
<div class="counter">3</div> <div class="counter">29</div>
<p>tests</p> <p>tests</p>
</div> </div>
</td> </td>
@ -38,7 +38,7 @@
</td> </td>
<td> <td>
<div class="infoBox" id="duration"> <div class="infoBox" id="duration">
<div class="counter">1.064s</div> <div class="counter">11.231s</div>
<p>duration</p> <p>duration</p>
</div> </div>
</td> </td>
@ -80,12 +80,72 @@
<tbody> <tbody>
<tr> <tr>
<td class="success"> <td class="success">
<a href="packages/com.unicorn.lifesub.member.test.unit.config.jwt.html">com.unicorn.lifesub.member.test.unit.config.jwt</a> <a href="packages/com.unicorn.lifesub.member.test.e2e.html">com.unicorn.lifesub.member.test.e2e</a>
</td> </td>
<td>3</td> <td>3</td>
<td>0</td> <td>0</td>
<td>0</td> <td>0</td>
<td>1.064s</td> <td>7.088s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="packages/com.unicorn.lifesub.member.test.integration.controller.html">com.unicorn.lifesub.member.test.integration.controller</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.781s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="packages/com.unicorn.lifesub.member.test.integration.repository.html">com.unicorn.lifesub.member.test.integration.repository</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.625s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="packages/com.unicorn.lifesub.member.test.integration.service.html">com.unicorn.lifesub.member.test.integration.service</a>
</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>1.729s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="packages/com.unicorn.lifesub.member.test.unit.config.jwt.html">com.unicorn.lifesub.member.test.unit.config.jwt</a>
</td>
<td>8</td>
<td>0</td>
<td>0</td>
<td>0.945s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="packages/com.unicorn.lifesub.member.test.unit.domain.html">com.unicorn.lifesub.member.test.unit.domain</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.008s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="packages/com.unicorn.lifesub.member.test.unit.service.html">com.unicorn.lifesub.member.test.unit.service</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.055s</td>
<td class="success">100%</td> <td class="success">100%</td>
</tr> </tr>
</tbody> </tbody>
@ -107,12 +167,82 @@
<tbody> <tbody>
<tr> <tr>
<td class="success"> <td class="success">
<a href="classes/com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceTest.html">com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceTest</a> <a href="classes/com.unicorn.lifesub.member.test.e2e.MemberE2ETest.html">com.unicorn.lifesub.member.test.e2e.MemberE2ETest</a>
</td> </td>
<td>3</td> <td>3</td>
<td>0</td> <td>0</td>
<td>0</td> <td>0</td>
<td>1.064s</td> <td>7.088s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="classes/com.unicorn.lifesub.member.test.integration.controller.MemberControllerIntegrationTest.html">com.unicorn.lifesub.member.test.integration.controller.MemberControllerIntegrationTest</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.781s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="classes/com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest.html">com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.625s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="classes/com.unicorn.lifesub.member.test.integration.service.MemberServiceIntegrationTest.html">com.unicorn.lifesub.member.test.integration.service.MemberServiceIntegrationTest</a>
</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>1.729s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="classes/com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceUnitTest.html">com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceUnitTest</a>
</td>
<td>3</td>
<td>0</td>
<td>0</td>
<td>0.112s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="classes/com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest.html">com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest</a>
</td>
<td>5</td>
<td>0</td>
<td>0</td>
<td>0.833s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="classes/com.unicorn.lifesub.member.test.unit.domain.MemberUnitTest.html">com.unicorn.lifesub.member.test.unit.domain.MemberUnitTest</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.008s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="classes/com.unicorn.lifesub.member.test.unit.service.MemberServiceImplUnitTest.html">com.unicorn.lifesub.member.test.unit.service.MemberServiceImplUnitTest</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.055s</td>
<td class="success">100%</td> <td class="success">100%</td>
</tr> </tr>
</tbody> </tbody>
@ -126,7 +256,7 @@
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/> <input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label> </label>
</div>Generated by </div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 4:50:22</p> <a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div> </div>
</div> </div>
</body> </body>

View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Package com.unicorn.lifesub.member.test.e2e</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Package com.unicorn.lifesub.member.test.e2e</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt; com.unicorn.lifesub.member.test.e2e</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">3</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">7.088s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Classes</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Classes</h2>
<table>
<thread>
<tr>
<th>Class</th>
<th>Tests</th>
<th>Failures</th>
<th>Ignored</th>
<th>Duration</th>
<th>Success rate</th>
</tr>
</thread>
<tr>
<td class="success">
<a href="../classes/com.unicorn.lifesub.member.test.e2e.MemberE2ETest.html">MemberE2ETest</a>
</td>
<td>3</td>
<td>0</td>
<td>0</td>
<td>7.088s</td>
<td class="success">100%</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Package com.unicorn.lifesub.member.test.integration.controller</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Package com.unicorn.lifesub.member.test.integration.controller</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt; com.unicorn.lifesub.member.test.integration.controller</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">4</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.781s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Classes</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Classes</h2>
<table>
<thread>
<tr>
<th>Class</th>
<th>Tests</th>
<th>Failures</th>
<th>Ignored</th>
<th>Duration</th>
<th>Success rate</th>
</tr>
</thread>
<tr>
<td class="success">
<a href="../classes/com.unicorn.lifesub.member.test.integration.controller.MemberControllerIntegrationTest.html">MemberControllerIntegrationTest</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.781s</td>
<td class="success">100%</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Package com.unicorn.lifesub.member.test.integration.repository</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Package com.unicorn.lifesub.member.test.integration.repository</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt; com.unicorn.lifesub.member.test.integration.repository</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">4</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.625s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Classes</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Classes</h2>
<table>
<thread>
<tr>
<th>Class</th>
<th>Tests</th>
<th>Failures</th>
<th>Ignored</th>
<th>Duration</th>
<th>Success rate</th>
</tr>
</thread>
<tr>
<td class="success">
<a href="../classes/com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest.html">MemberRepositoryIntegrationTest</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.625s</td>
<td class="success">100%</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Package com.unicorn.lifesub.member.test.integration.service</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Package com.unicorn.lifesub.member.test.integration.service</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt; com.unicorn.lifesub.member.test.integration.service</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">2</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">1.729s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Classes</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Classes</h2>
<table>
<thread>
<tr>
<th>Class</th>
<th>Tests</th>
<th>Failures</th>
<th>Ignored</th>
<th>Duration</th>
<th>Success rate</th>
</tr>
</thread>
<tr>
<td class="success">
<a href="../classes/com.unicorn.lifesub.member.test.integration.service.MemberServiceIntegrationTest.html">MemberServiceIntegrationTest</a>
</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>1.729s</td>
<td class="success">100%</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -22,7 +22,7 @@
<tr> <tr>
<td> <td>
<div class="infoBox" id="tests"> <div class="infoBox" id="tests">
<div class="counter">3</div> <div class="counter">8</div>
<p>tests</p> <p>tests</p>
</div> </div>
</td> </td>
@ -40,7 +40,7 @@
</td> </td>
<td> <td>
<div class="infoBox" id="duration"> <div class="infoBox" id="duration">
<div class="counter">1.064s</div> <div class="counter">0.945s</div>
<p>duration</p> <p>duration</p>
</div> </div>
</td> </td>
@ -78,12 +78,22 @@
</thread> </thread>
<tr> <tr>
<td class="success"> <td class="success">
<a href="../classes/com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceTest.html">CustomUserDetailsServiceTest</a> <a href="../classes/com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceUnitTest.html">CustomUserDetailsServiceUnitTest</a>
</td> </td>
<td>3</td> <td>3</td>
<td>0</td> <td>0</td>
<td>0</td> <td>0</td>
<td>1.064s</td> <td>0.112s</td>
<td class="success">100%</td>
</tr>
<tr>
<td class="success">
<a href="../classes/com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest.html">JwtTokenProviderUnitTest</a>
</td>
<td>5</td>
<td>0</td>
<td>0</td>
<td>0.833s</td>
<td class="success">100%</td> <td class="success">100%</td>
</tr> </tr>
</table> </table>
@ -96,7 +106,7 @@
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/> <input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label> </label>
</div>Generated by </div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 4:50:22</p> <a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div> </div>
</div> </div>
</body> </body>

View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Package com.unicorn.lifesub.member.test.unit.domain</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Package com.unicorn.lifesub.member.test.unit.domain</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt; com.unicorn.lifesub.member.test.unit.domain</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">4</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.008s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Classes</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Classes</h2>
<table>
<thread>
<tr>
<th>Class</th>
<th>Tests</th>
<th>Failures</th>
<th>Ignored</th>
<th>Duration</th>
<th>Success rate</th>
</tr>
</thread>
<tr>
<td class="success">
<a href="../classes/com.unicorn.lifesub.member.test.unit.domain.MemberUnitTest.html">MemberUnitTest</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.008s</td>
<td class="success">100%</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Package com.unicorn.lifesub.member.test.unit.service</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Package com.unicorn.lifesub.member.test.unit.service</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt; com.unicorn.lifesub.member.test.unit.service</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">4</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.055s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Classes</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Classes</h2>
<table>
<thread>
<tr>
<th>Class</th>
<th>Tests</th>
<th>Failures</th>
<th>Ignored</th>
<th>Duration</th>
<th>Success rate</th>
</tr>
</thread>
<tr>
<td class="success">
<a href="../classes/com.unicorn.lifesub.member.test.unit.service.MemberServiceImplUnitTest.html">MemberServiceImplUnitTest</a>
</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0.055s</td>
<td class="success">100%</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 8.4</a> at 2025. 2. 14. 오후 11:46:27</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,35 @@
# src/test/resources/application-e2e-test.yml
spring:
application:
name: member-service-test
jpa:
hibernate:
ddl-auto: create-drop
show-sql: true
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.PostgreSQLDialect
# JWT 설정
jwt:
secret-key: testSecretKeyForE2ETestingPurposesOnlyDoNotUseInProduction
access-token-validity: 3600000 # 1시간
refresh-token-validity: 86400000 # 24시간
allowed-origins: http://localhost:3000
# 로깅 설정
logging:
level:
com.unicorn: DEBUG
org.hibernate.SQL: DEBUG
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
# 테스트용 사용자 설정
test:
user:
id: testuser
password: Test1234!
name: Test User

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.unicorn.lifesub.member.test.integration.controller.MemberControllerIntegrationTest" tests="4" skipped="0" failures="0" errors="0" timestamp="2025-02-14T14:45:42" hostname="ihaegyeong-ui-MacBookAir.local" time="0.804">
<properties/>
<testcase name="로그아웃 성공 테스트" classname="com.unicorn.lifesub.member.test.integration.controller.MemberControllerIntegrationTest" time="0.551"/>
<testcase name="로그인 실패 테스트 - 잘못된 요청 형식" classname="com.unicorn.lifesub.member.test.integration.controller.MemberControllerIntegrationTest" time="0.11"/>
<testcase name="로그아웃 실패 테스트 - 잘못된 요청 형식" classname="com.unicorn.lifesub.member.test.integration.controller.MemberControllerIntegrationTest" time="0.06"/>
<testcase name="로그인 성공 테스트" classname="com.unicorn.lifesub.member.test.integration.controller.MemberControllerIntegrationTest" time="0.06"/>
<system-out><![CDATA[
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.0)
2025-02-14T23:45:39.822+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.c.MemberControllerIntegrationTest : Starting MemberControllerIntegrationTest using Java 18.0.2 with PID 99945 (started by ondal in /Users/ondal/home/workspace/lifesub/member)
2025-02-14T23:45:39.825+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] .m.t.i.c.MemberControllerIntegrationTest : Running with Spring Boot v3.4.0, Spring v6.2.0
2025-02-14T23:45:39.825+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.c.MemberControllerIntegrationTest : The following 1 profile is active: "integration-test"
2025-02-14T23:45:40.778+09:00 WARN 99945 --- [member-service-test] [ Test worker] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 6aa45464-02a7-4558-8a92-e66c40f4756b
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2025-02-14T23:45:40.793+09:00 INFO 99945 --- [member-service-test] [ Test worker] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
2025-02-14T23:45:42.817+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring TestDispatcherServlet ''
2025-02-14T23:45:42.821+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
2025-02-14T23:45:42.830+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 5 ms
2025-02-14T23:45:42.954+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.c.MemberControllerIntegrationTest : Started MemberControllerIntegrationTest in 3.343 seconds (process running for 65.774)
2025-02-14T23:45:43.628+09:00 WARN 99945 --- [member-service-test] [ Test worker] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<com.unicorn.lifesub.common.dto.ApiResponse<com.unicorn.lifesub.common.dto.JwtTokenDTO>> com.unicorn.lifesub.member.controller.MemberController.login(com.unicorn.lifesub.member.dto.LoginRequest) with 2 errors: [Field error in object 'loginRequest' on field 'password': rejected value [null]; codes [NotBlank.loginRequest.password,NotBlank.password,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [loginRequest.password,password]; arguments []; default message [password]]; default message [비밀번호는 필수입니다.]] [Field error in object 'loginRequest' on field 'userId': rejected value [null]; codes [NotBlank.loginRequest.userId,NotBlank.userId,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [loginRequest.userId,userId]; arguments []; default message [userId]]; default message [사용자 ID는 필수입니다.]] ]
2025-02-14T23:45:43.705+09:00 WARN 99945 --- [member-service-test] [ Test worker] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<com.unicorn.lifesub.common.dto.ApiResponse<com.unicorn.lifesub.member.dto.LogoutResponse>> com.unicorn.lifesub.member.controller.MemberController.logout(com.unicorn.lifesub.member.dto.LogoutRequest): [Field error in object 'logoutRequest' on field 'userId': rejected value [null]; codes [NotBlank.logoutRequest.userId,NotBlank.userId,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [logoutRequest.userId,userId]; arguments []; default message [userId]]; default message [사용자 ID는 필수입니다.]] ]
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>

View File

@ -0,0 +1,411 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest" tests="4" skipped="0" failures="0" errors="0" timestamp="2025-02-14T14:45:51" hostname="ihaegyeong-ui-MacBookAir.local" time="0.67">
<properties/>
<testcase name="회원 저장 및 조회 테스트" classname="com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest" time="0.341"/>
<testcase name="회원 정보 업데이트 테스트" classname="com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest" time="0.178"/>
<testcase name="존재하지 않는 회원 조회 테스트" classname="com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest" time="0.025"/>
<testcase name="회원 삭제 테스트" classname="com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest" time="0.081"/>
<system-out><![CDATA[2025-02-14T23:45:43.930+09:00 INFO 99945 --- [member-service-test] [ Test worker] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest]: MemberRepositoryIntegrationTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2025-02-14T23:45:44.293+09:00 INFO 99945 --- [member-service-test] [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.unicorn.lifesub.member.MemberApplication for test class com.unicorn.lifesub.member.test.integration.repository.MemberRepositoryIntegrationTest
2025-02-14T23:45:44.315+09:00 INFO 99945 --- [member-service-test] [ Test worker] tc.postgres:13.2-alpine : Creating container for image: postgres:13.2-alpine
2025-02-14T23:45:44.451+09:00 INFO 99945 --- [member-service-test] [ Test worker] tc.postgres:13.2-alpine : Container postgres:13.2-alpine is starting: 6b79d075221360d24585825bd669f3f2099a36a70cc40b3b166e8fb6762cc3e9
2025-02-14T23:45:46.654+09:00 INFO 99945 --- [member-service-test] [ Test worker] tc.postgres:13.2-alpine : Container postgres:13.2-alpine started in PT2.338311S
2025-02-14T23:45:46.673+09:00 INFO 99945 --- [member-service-test] [ Test worker] tc.postgres:13.2-alpine : Container is started (JDBC URL: jdbc:postgresql://localhost:58666/member?loggerLevel=OFF)
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.0)
2025-02-14T23:45:47.048+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.r.MemberRepositoryIntegrationTest : Starting MemberRepositoryIntegrationTest using Java 18.0.2 with PID 99945 (started by ondal in /Users/ondal/home/workspace/lifesub/member)
2025-02-14T23:45:47.050+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] .m.t.i.r.MemberRepositoryIntegrationTest : Running with Spring Boot v3.4.0, Spring v6.2.0
2025-02-14T23:45:47.058+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.r.MemberRepositoryIntegrationTest : The following 1 profile is active: "integration-test"
2025-02-14T23:45:48.793+09:00 INFO 99945 --- [member-service-test] [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-02-14T23:45:48.950+09:00 INFO 99945 --- [member-service-test] [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 107 ms. Found 1 JPA repository interface.
2025-02-14T23:45:49.932+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2025-02-14T23:45:49.958+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled
2025-02-14T23:45:50.150+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
2025-02-14T23:45:50.161+09:00 INFO 99945 --- [member-service-test] [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Starting...
2025-02-14T23:45:50.266+09:00 INFO 99945 --- [member-service-test] [ Test worker] com.zaxxer.hikari.pool.HikariPool : HikariPool-2 - Added connection org.postgresql.jdbc.PgConnection@54210bb8
2025-02-14T23:45:50.272+09:00 INFO 99945 --- [member-service-test] [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Start completed.
2025-02-14T23:45:50.290+09:00 WARN 99945 --- [member-service-test] [ Test worker] org.hibernate.orm.deprecation : HHH90000025: PostgreSQLDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
2025-02-14T23:45:50.300+09:00 INFO 99945 --- [member-service-test] [ Test worker] org.hibernate.orm.connections.pooling : HHH10001005: Database info:
Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-2)']
Database driver: undefined/unknown
Database version: 13.2
Autocommit mode: undefined/unknown
Isolation level: undefined/unknown
Minimum pool size: undefined/unknown
Maximum pool size: undefined/unknown
2025-02-14T23:45:50.938+09:00 INFO 99945 --- [member-service-test] [ Test worker] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2025-02-14T23:45:51.157+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
create table member_roles (
user_id varchar(255) not null,
role varchar(255)
)
Hibernate:
create table member_roles (
user_id varchar(255) not null,
role varchar(255)
)
2025-02-14T23:45:51.193+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
create table members (
user_id varchar(255) not null,
created_at timestamp(6),
updated_at timestamp(6),
password varchar(255) not null,
user_name varchar(255) not null,
primary key (user_id)
)
Hibernate:
create table members (
user_id varchar(255) not null,
created_at timestamp(6),
updated_at timestamp(6),
password varchar(255) not null,
user_name varchar(255) not null,
primary key (user_id)
)
2025-02-14T23:45:51.224+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
alter table if exists member_roles
add constraint FKkrahbaoj05n0hyabejnnrmft
foreign key (user_id)
references members
Hibernate:
alter table if exists member_roles
add constraint FKkrahbaoj05n0hyabejnnrmft
foreign key (user_id)
references members
2025-02-14T23:45:51.242+09:00 INFO 99945 --- [member-service-test] [ Test worker] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-02-14T23:45:51.723+09:00 INFO 99945 --- [member-service-test] [ Test worker] .m.t.i.r.MemberRepositoryIntegrationTest : Started MemberRepositoryIntegrationTest in 5.01 seconds (process running for 74.544)
2025-02-14T23:45:51.942+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
2025-02-14T23:45:51.963+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
member_roles
(user_id, role)
values
(?, ?)
Hibernate:
insert
into
member_roles
(user_id, role)
values
(?, ?)
2025-02-14T23:45:52.003+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
2025-02-14T23:45:52.033+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
Hibernate:
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
2025-02-14T23:45:52.180+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
2025-02-14T23:45:52.188+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
member_roles
(user_id, role)
values
(?, ?)
Hibernate:
insert
into
member_roles
(user_id, role)
values
(?, ?)
2025-02-14T23:45:52.195+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
2025-02-14T23:45:52.203+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
Hibernate:
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
2025-02-14T23:45:52.284+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
update
members
set
created_at=?,
password=?,
updated_at=?,
user_name=?
where
user_id=?
Hibernate:
update
members
set
created_at=?,
password=?,
updated_at=?,
user_name=?
where
user_id=?
2025-02-14T23:45:52.312+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
2025-02-14T23:45:52.318+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
Hibernate:
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
2025-02-14T23:45:52.367+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
2025-02-14T23:45:52.394+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
members
(created_at, password, updated_at, user_name, user_id)
values
(?, ?, ?, ?, ?)
2025-02-14T23:45:52.400+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
insert
into
member_roles
(user_id, role)
values
(?, ?)
Hibernate:
insert
into
member_roles
(user_id, role)
values
(?, ?)
2025-02-14T23:45:52.404+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
2025-02-14T23:45:52.408+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
Hibernate:
select
r1_0.user_id,
r1_0.role
from
member_roles r1_0
where
r1_0.user_id=?
2025-02-14T23:45:52.437+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
delete
from
member_roles
where
user_id=?
Hibernate:
delete
from
member_roles
where
user_id=?
2025-02-14T23:45:52.444+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
delete
from
members
where
user_id=?
Hibernate:
delete
from
members
where
user_id=?
2025-02-14T23:45:52.453+09:00 DEBUG 99945 --- [member-service-test] [ Test worker] org.hibernate.SQL :
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
Hibernate:
select
me1_0.user_id,
me1_0.created_at,
me1_0.password,
me1_0.updated_at,
me1_0.user_name
from
members me1_0
where
me1_0.user_id=?
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.unicorn.lifesub.member.test.integration.service.MemberServiceIntegrationTest" tests="2" skipped="0" failures="0" errors="0" timestamp="2025-02-14T14:45:53" hostname="ihaegyeong-ui-MacBookAir.local" time="1.771">
<properties/>
<testcase name="로그아웃 처리 성공" classname="com.unicorn.lifesub.member.test.integration.service.MemberServiceIntegrationTest" time="1.518"/>
<testcase name="유효한 자격증명으로 로그인 성공" classname="com.unicorn.lifesub.member.test.integration.service.MemberServiceIntegrationTest" time="0.211"/>
<system-out><![CDATA[]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceTest" tests="3" skipped="0" failures="0" errors="0" timestamp="2025-02-14T07:50:21" hostname="ihaegyeong-ui-MacBookAir.local" time="1.069"> <testsuite name="com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceUnitTest" tests="3" skipped="0" failures="0" errors="0" timestamp="2025-02-14T14:45:54" hostname="ihaegyeong-ui-MacBookAir.local" time="0.121">
<properties/> <properties/>
<testcase name="givenNonExistentUserId_whenLoadUser_thenThrowException" classname="com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceTest" time="0.864"/> <testcase name="givenNonExistentUserId_whenLoadUser_thenThrowException" classname="com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceUnitTest" time="0.064"/>
<testcase name="givenUserWithRoles_whenLoadUser_thenMapAuthoritiesCorrectly" classname="com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceTest" time="0.192"/> <testcase name="givenUserWithRoles_whenLoadUser_thenMapAuthoritiesCorrectly" classname="com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceUnitTest" time="0.041"/>
<testcase name="givenExistingUserId_whenLoadUser_thenReturnUserDetails" classname="com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceTest" time="0.008"/> <testcase name="givenExistingUserId_whenLoadUser_thenReturnUserDetails" classname="com.unicorn.lifesub.member.test.unit.config.jwt.CustomUserDetailsServiceUnitTest" time="0.007"/>
<system-out><![CDATA[]]></system-out> <system-out><![CDATA[]]></system-out>
<system-err><![CDATA[]]></system-err> <system-err><![CDATA[]]></system-err>
</testsuite> </testsuite>

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest" tests="5" skipped="0" failures="0" errors="0" timestamp="2025-02-14T14:45:55" hostname="ihaegyeong-ui-MacBookAir.local" time="0.846">
<properties/>
<testcase name="givenRequest_whenResolveToken_thenSuccess" classname="com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest" time="0.673"/>
<testcase name="givenInvalidToken_whenValidate_thenThrowException" classname="com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest" time="0.119"/>
<testcase name="givenValidMember_whenCreateToken_thenSuccess" classname="com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest" time="0.028"/>
<testcase name="givenValidToken_whenGetAuthentication_thenSuccess" classname="com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest" time="0.007"/>
<testcase name="givenToken_whenValidate_thenSuccess" classname="com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest" time="0.006"/>
<system-out><![CDATA[2025-02-14T23:45:55.728+09:00 INFO 99945 --- [member-service-test] [ Test worker] c.u.l.m.config.jwt.JwtTokenProvider : ******** validateToken: invalid-token
2025-02-14T23:45:55.759+09:00 ERROR 99945 --- [member-service-test] [ Test worker] c.u.l.m.config.jwt.JwtTokenProvider : Undefined Error: The token was expected to have 3 parts, but got 0.
com.auth0.jwt.exceptions.JWTDecodeException: The token was expected to have 3 parts, but got 0.
at com.auth0.jwt.TokenUtils.wrongNumberOfParts(TokenUtils.java:45) ~[java-jwt-4.4.0.jar:4.4.0]
at com.auth0.jwt.TokenUtils.splitToken(TokenUtils.java:23) ~[java-jwt-4.4.0.jar:4.4.0]
at com.auth0.jwt.JWTDecoder.<init>(JWTDecoder.java:37) ~[java-jwt-4.4.0.jar:4.4.0]
at com.auth0.jwt.JWTVerifier.verify(JWTVerifier.java:444) ~[java-jwt-4.4.0.jar:4.4.0]
at com.unicorn.lifesub.member.config.jwt.JwtTokenProvider.validateToken(JwtTokenProvider.java:112) ~[main/:na]
at com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest.lambda$givenInvalidToken_whenValidate_thenThrowException$0(JwtTokenProviderUnitTest.java:126) ~[test/:na]
at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:53) ~[junit-jupiter-api-5.11.3.jar:5.11.3]
at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:35) ~[junit-jupiter-api-5.11.3.jar:5.11.3]
at org.junit.jupiter.api.Assertions.assertThrows(Assertions.java:3128) ~[junit-jupiter-api-5.11.3.jar:5.11.3]
at com.unicorn.lifesub.member.test.unit.config.jwt.JwtTokenProviderUnitTest.givenInvalidToken_whenValidate_thenThrowException(JwtTokenProviderUnitTest.java:126) ~[test/:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:767) ~[junit-platform-commons-1.11.3.jar:1.11.3]
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$8(TestMethodTestDescriptor.java:217) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) ~[junit-jupiter-engine-5.11.3.jar:5.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:156) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:160) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:160) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) ~[junit-platform-engine-1.11.3.jar:1.11.3]
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) ~[junit-platform-launcher-1.8.2.jar:1.8.2]
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:119) ~[na:na]
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:94) ~[na:na]
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:89) ~[na:na]
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) ~[na:na]
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) ~[na:na]
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) ~[na:na]
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) ~[na:na]
at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source) ~[na:na]
at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) ~[na:na]
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) ~[na:na]
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) ~[na:na]
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) ~[na:na]
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) ~[na:na]
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113) ~[na:na]
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65) ~[na:na]
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) ~[gradle-worker.jar:na]
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) ~[gradle-worker.jar:na]
2025-02-14T23:45:55.832+09:00 INFO 99945 --- [member-service-test] [ Test worker] c.u.l.m.config.jwt.JwtTokenProvider : ******** validateToken: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0VXNlciIsInVzZXJJZCI6InRlc3RVc2VyIiwidXNlck5hbWUiOiJUZXN0IFVzZXIiLCJhdXRoIjpbIlJPTEVfVVNFUiJdLCJpYXQiOjE3Mzk1NDQzNTUsImV4cCI6MTc0MzE0NDM1NX0.mdBFO7WH3XMHafHC6WpEQ-j8D_uNHq8HnxubMgpfIhq6rkIOdOMO0w1iN0gskTyJOgxGAxe8P5LwynLSUO8jEQ
2025-02-14T23:45:55.859+09:00 INFO 99945 --- [member-service-test] [ Test worker] c.u.l.m.config.jwt.JwtTokenProvider : ******** validateToken: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0VXNlciIsImF1dGgiOlsiUk9MRV9VU0VSIl19.s0nwJ9sbCd7YYRCIj2yGgbuNP3KgpZ5SssKSOoo_FDg8mCrxilGVMaiv2gPGq0q0hx_RC413cAeMM-Y4nurEIw
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.unicorn.lifesub.member.test.unit.domain.MemberUnitTest" tests="4" skipped="0" failures="0" errors="0" timestamp="2025-02-14T14:45:55" hostname="ihaegyeong-ui-MacBookAir.local" time="0.011">
<properties/>
<testcase name="givenMemberDomain_whenConvertToEntity_thenSuccess" classname="com.unicorn.lifesub.member.test.unit.domain.MemberUnitTest" time="0.003"/>
<testcase name="givenMemberEntity_whenConvertToDomain_thenSuccess" classname="com.unicorn.lifesub.member.test.unit.domain.MemberUnitTest" time="0.0"/>
<testcase name="givenMemberInfo_whenBuildMember_thenSuccess" classname="com.unicorn.lifesub.member.test.unit.domain.MemberUnitTest" time="0.002"/>
<testcase name="givenMultipleRoles_whenBuildMember_thenSuccess" classname="com.unicorn.lifesub.member.test.unit.domain.MemberUnitTest" time="0.003"/>
<system-out><![CDATA[]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.unicorn.lifesub.member.test.unit.service.MemberServiceImplUnitTest" tests="4" skipped="0" failures="0" errors="0" timestamp="2025-02-14T14:45:55" hostname="ihaegyeong-ui-MacBookAir.local" time="0.059">
<properties/>
<testcase name="givenValidCredentials_whenLogin_thenSuccess" classname="com.unicorn.lifesub.member.test.unit.service.MemberServiceImplUnitTest" time="0.02"/>
<testcase name="givenLogoutRequest_whenLogout_thenSuccess" classname="com.unicorn.lifesub.member.test.unit.service.MemberServiceImplUnitTest" time="0.01"/>
<testcase name="givenInvalidPassword_whenLogin_thenThrowException" classname="com.unicorn.lifesub.member.test.unit.service.MemberServiceImplUnitTest" time="0.017"/>
<testcase name="givenNonExistentUser_whenLogin_thenThrowException" classname="com.unicorn.lifesub.member.test.unit.service.MemberServiceImplUnitTest" time="0.008"/>
<system-out><![CDATA[]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>

View File

@ -1,8 +1,8 @@
package com.unicorn.lifesub.member.config; package com.unicorn.lifesub.member.config;
import com.unicorn.lifesub.member.config.jwt.CustomUserDetailsService; import com.unicorn.lifesub.member.config.jwt.CustomUserDetailsService;
import com.unicorn.lifesub.member.config.jwt.JwtTokenProvider;
import com.unicorn.lifesub.member.config.jwt.JwtAuthenticationFilter; import com.unicorn.lifesub.member.config.jwt.JwtAuthenticationFilter;
import com.unicorn.lifesub.member.config.jwt.JwtTokenProvider;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;

View File

@ -2,12 +2,17 @@ package com.unicorn.lifesub.member.controller;
import com.unicorn.lifesub.common.dto.ApiResponse; import com.unicorn.lifesub.common.dto.ApiResponse;
import com.unicorn.lifesub.common.dto.JwtTokenDTO; import com.unicorn.lifesub.common.dto.JwtTokenDTO;
import com.unicorn.lifesub.member.dto.*; import com.unicorn.lifesub.common.exception.BusinessException;
import com.unicorn.lifesub.common.exception.InfraException;
import com.unicorn.lifesub.member.dto.LoginRequest;
import com.unicorn.lifesub.member.dto.LogoutRequest;
import com.unicorn.lifesub.member.dto.LogoutResponse;
import com.unicorn.lifesub.member.service.MemberService; import com.unicorn.lifesub.member.service.MemberService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -24,8 +29,18 @@ public class MemberController {
@Operation(summary = "로그인", description = "사용자 ID와 비밀번호로 로그인합니다.") @Operation(summary = "로그인", description = "사용자 ID와 비밀번호로 로그인합니다.")
@PostMapping("/login") @PostMapping("/login")
public ResponseEntity<ApiResponse<JwtTokenDTO>> login(@Valid @RequestBody LoginRequest request) { public ResponseEntity<ApiResponse<JwtTokenDTO>> login(@Valid @RequestBody LoginRequest request) {
try {
JwtTokenDTO response = memberService.login(request); JwtTokenDTO response = memberService.login(request);
return ResponseEntity.ok(ApiResponse.success(response)); return ResponseEntity.ok(ApiResponse.success(response));
} catch (BusinessException e) {
return ResponseEntity
.status(HttpStatus.UNAUTHORIZED)
.body(ApiResponse.error(e.getErrorCode()));
} catch (InfraException e) {
return ResponseEntity
.status(HttpStatus.UNAUTHORIZED)
.body(ApiResponse.error(e.getErrorCode()));
}
} }
@Operation(summary = "로그아웃", description = "현재 로그인된 사용자를 로그아웃합니다.") @Operation(summary = "로그아웃", description = "현재 로그인된 사용자를 로그아웃합니다.")

View File

@ -55,4 +55,8 @@ public class MemberEntity extends BaseTimeEntity {
.roles(member.getRoles()) .roles(member.getRoles())
.build(); .build();
} }
public void updateUserName(String userName) {
this.userName = userName;
}
} }

View File

@ -33,15 +33,15 @@ public class MemberServiceImpl implements MemberService {
MemberEntity member = memberRepository.findByUserId(request.getUserId()) MemberEntity member = memberRepository.findByUserId(request.getUserId())
.orElseThrow(() -> new InfraException(ErrorCode.MEMBER_NOT_FOUND)); .orElseThrow(() -> new InfraException(ErrorCode.MEMBER_NOT_FOUND));
if (!passwordEncoder.matches(request.getPassword(), member.getPassword())) {
throw new BusinessException(ErrorCode.INVALID_CREDENTIALS);
}
// 사용자의 권한 정보 생성 // 사용자의 권한 정보 생성
Collection<? extends GrantedAuthority> authorities = member.getRoles().stream() Collection<? extends GrantedAuthority> authorities = member.getRoles().stream()
.map(SimpleGrantedAuthority::new) .map(SimpleGrantedAuthority::new)
.collect(Collectors.toList()); .collect(Collectors.toList());
if (!passwordEncoder.matches(request.getPassword(), member.getPassword())) {
throw new BusinessException(ErrorCode.INVALID_CREDENTIALS);
}
return jwtTokenProvider.createToken(member, authorities); return jwtTokenProvider.createToken(member, authorities);
} }

View File

@ -0,0 +1,144 @@
package com.unicorn.lifesub.member.test.e2e;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.unicorn.lifesub.common.dto.ApiResponse;
import com.unicorn.lifesub.common.dto.JwtTokenDTO;
import com.unicorn.lifesub.member.dto.LoginRequest;
import com.unicorn.lifesub.member.dto.LogoutRequest;
import com.unicorn.lifesub.member.repository.jpa.MemberRepository;
import com.unicorn.lifesub.member.test.e2e.config.TestContainerConfig;
import com.unicorn.lifesub.member.test.e2e.support.TestDataManager;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.test.web.servlet.client.MockMvcWebTestClient;
import org.springframework.web.context.WebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("e2e-test")
class MemberE2ETest extends TestContainerConfig {
@Autowired
private WebApplicationContext context;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private TestDataManager testDataManager;
@Autowired
private MemberRepository memberRepository;
private WebTestClient webClient;
@Value("${test.user.id}")
private String TEST_USER_ID;
@Value("${test.user.password}")
private String TEST_PASSWORD;
@BeforeEach
void setUp() {
webClient = MockMvcWebTestClient
.bindToApplicationContext(context)
.apply(SecurityMockMvcConfigurers.springSecurity())
.configureClient()
.build();
memberRepository.deleteAll();
testDataManager.setupTestData();
}
@Test
@DisplayName("로그인 성공 시나리오")
void givenValidCredentials_whenLogin_thenSuccess() {
// Given
LoginRequest loginRequest = createLoginRequest(TEST_USER_ID, TEST_PASSWORD);
// When & Then
webClient.post().uri("/api/auth/login")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(loginRequest)
.exchange()
.expectStatus().isOk()
.expectBody(ApiResponse.class)
.value(response -> {
assertThat(response.getStatus()).isEqualTo(200);
JwtTokenDTO jwtToken = objectMapper.convertValue(response.getData(), JwtTokenDTO.class);
assertThat(jwtToken.getAccessToken()).isNotNull();
assertThat(jwtToken.getRefreshToken()).isNotNull();
});
}
@Test
@DisplayName("잘못된 비밀번호로 로그인 실패 시나리오")
void givenInvalidPassword_whenLogin_thenFail() {
// Given
LoginRequest loginRequest = createLoginRequest(TEST_USER_ID, "wrongpassword");
// When & Then
webClient.post().uri("/api/auth/login")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(loginRequest)
.exchange()
.expectStatus().isUnauthorized()
.expectBody(ApiResponse.class)
.value(response -> {
assertThat(response.getStatus()).isEqualTo(210);
assertThat(response.getMessage()).isEqualTo("Invalid credentials");
});
}
@Test
@DisplayName("로그인 후 로그아웃 시나리오")
void givenValidToken_whenLogout_thenSuccess() {
// Given - 먼저 로그인
LoginRequest loginRequest = createLoginRequest(TEST_USER_ID, TEST_PASSWORD);
ApiResponse loginResponse = webClient.post().uri("/api/auth/login")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(loginRequest)
.exchange()
.expectStatus().isOk()
.expectBody(ApiResponse.class)
.returnResult()
.getResponseBody();
JwtTokenDTO tokenDTO = objectMapper.convertValue(loginResponse.getData(), JwtTokenDTO.class);
// When - 로그아웃
LogoutRequest logoutRequest = new LogoutRequest();
logoutRequest.setUserId(TEST_USER_ID);
// Then
webClient.post().uri("/api/auth/logout")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + tokenDTO.getAccessToken())
.bodyValue(logoutRequest)
.exchange()
.expectStatus().isOk()
.expectBody(ApiResponse.class)
.value(response -> {
assertThat(response.getStatus()).isEqualTo(200);
assertThat(response.getMessage()).contains("Success");
});
}
private LoginRequest createLoginRequest(String userId, String password) {
LoginRequest request = new LoginRequest();
request.setUserId(userId);
request.setPassword(password);
return request;
}
}

View File

@ -0,0 +1,25 @@
// TestContainerConfig.java
package com.unicorn.lifesub.member.test.e2e.config;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@Testcontainers
public class TestContainerConfig {
@Container
static PostgreSQLContainer<?> postgreSQLContainer = new PostgreSQLContainer<>("postgres:13.2-alpine")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
@DynamicPropertySource
static void registerPgProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl);
registry.add("spring.datasource.username", postgreSQLContainer::getUsername);
registry.add("spring.datasource.password", postgreSQLContainer::getPassword);
registry.add("spring.jpa.hibernate.ddl-auto", () -> "create-drop");
}
}

View File

@ -0,0 +1,68 @@
// TestDataManager.java
package com.unicorn.lifesub.member.test.e2e.support;
import com.unicorn.lifesub.member.repository.entity.MemberEntity;
import com.unicorn.lifesub.member.repository.jpa.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashSet;
import java.util.Set;
@Component
@RequiredArgsConstructor
public class TestDataManager {
private final MemberRepository memberRepository;
private final PasswordEncoder passwordEncoder;
@Value("${test.user.id}")
private String TEST_USER_ID;
@Value("${test.user.password}")
private String TEST_PASSWORD;
@Value("${test.user.name}")
private String TEST_USER_NAME;
@Transactional
public void setupTestData() {
if (memberRepository.count() == 0) {
// 기본 테스트 사용자 생성
createTestUser();
// 추가 테스트 데이터 생성
createAdditionalTestData();
}
}
private void createTestUser() {
Set<String> userRoles = new HashSet<>();
userRoles.add("USER");
MemberEntity testUser = MemberEntity.builder()
.userId(TEST_USER_ID)
.userName(TEST_USER_NAME)
.password(passwordEncoder.encode(TEST_PASSWORD)) // 암호화된 비밀번호 저장
.roles(userRoles)
.build();
memberRepository.save(testUser);
}
private void createAdditionalTestData() {
// 계정 잠금 테스트용 사용자
Set<String> userRoles = new HashSet<>();
userRoles.add("USER");
MemberEntity lockTestUser = MemberEntity.builder()
.userId("locktest")
.userName("Lock Test User")
.password(passwordEncoder.encode("lockpass"))
.roles(userRoles)
.build();
memberRepository.save(lockTestUser);
}
}

View File

@ -0,0 +1,23 @@
package com.unicorn.lifesub.member.test.integration.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@Profile("integration-test")
public class TestSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
}

View File

@ -0,0 +1,179 @@
package com.unicorn.lifesub.member.test.integration.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.unicorn.lifesub.common.dto.JwtTokenDTO;
import com.unicorn.lifesub.member.controller.MemberController;
import com.unicorn.lifesub.member.dto.LoginRequest;
import com.unicorn.lifesub.member.dto.LogoutRequest;
import com.unicorn.lifesub.member.dto.LogoutResponse;
import com.unicorn.lifesub.member.service.MemberService;
import com.unicorn.lifesub.member.test.integration.config.TestSecurityConfig;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* MemberController 통합 테스트 클래스
* 회원 인증 관련 API의 요청/응답을 검증합니다.
*
* @author Tera
* @version 1.0
*/
@WebMvcTest(MemberController.class)
@Import({MemberControllerIntegrationTest.TestConfig.class, TestSecurityConfig.class})
@ActiveProfiles("integration-test")
class MemberControllerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private MemberService memberService;
/**
* 테스트를 위한 설정 클래스입니다.
* Controller와 의존성들을 직접 등록하여 테스트 환경을 구성합니다.
*
* @implNote 1. Controller와 필요한 빈들을 직접 등록하여 의존성을 명확히 합니다.
* 2. Service는 Mockito를 통해 mock 객체로 대체하여 테스트를 격리합니다.
*/
@Configuration
static class TestConfig implements WebMvcConfigurer {
/**
* MemberController 빈을 등록합니다.
* memberService() 통해 Mock 객체를 주입받아 Controller를 생성합니다.
*
* @return MemberController 인스턴스
*/
@Bean
public MemberController memberController() {
return new MemberController(memberService());
}
/**
* MemberService Mock 객체를 생성하여 반환합니다.
* 실제 Service 구현체 대신 Mock 객체를 사용하여 테스트를 격리합니다.
*
* @return MemberService Mock 객체
*/
@Bean
public MemberService memberService() {
return mock(MemberService.class);
}
}
/**
* 로그인 성공 케이스를 테스트합니다.
* 올바른 사용자 ID와 비밀번호로 요청 JWT 토큰이 정상적으로 발급되는지 검증합니다.
*
* @throws Exception MockMvc 수행 발생할 있는 예외
*/
@Test
@DisplayName("로그인 성공 테스트")
void loginSuccess() throws Exception {
// Given: 테스트에 필요한 요청 데이터와 응답 객체를 준비
LoginRequest request = new LoginRequest();
request.setUserId("testUser");
request.setPassword("testPass");
JwtTokenDTO tokenDTO = JwtTokenDTO.builder()
.accessToken("test-access-token")
.refreshToken("test-refresh-token")
.build();
given(memberService.login(any(LoginRequest.class))).willReturn(tokenDTO);
// When & Then: API 호출 결과 검증
mockMvc.perform(post("/api/auth/login")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value(200))
.andExpect(jsonPath("$.data.accessToken").value("test-access-token"))
.andExpect(jsonPath("$.data.refreshToken").value("test-refresh-token"));
}
/**
* 로그인 실패 케이스를 테스트합니다.
* 잘못된 형식의 요청 데이터로 API 호출 적절한 에러 응답이 반환되는지 검증합니다.
*
* @throws Exception MockMvc 수행 발생할 있는 예외
*/
@Test
@DisplayName("로그인 실패 테스트 - 잘못된 요청 형식")
void loginFailInvalidRequest() throws Exception {
// Given: 검증에 실패하도록 필수 필드가 비어있는 요청 객체 생성
LoginRequest request = new LoginRequest();
// When & Then: API 호출 결과 검증
mockMvc.perform(post("/api/auth/login")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isBadRequest());
}
/**
* 로그아웃 성공 케이스를 테스트합니다.
* 정상적인 로그아웃 요청 성공 응답이 반환되는지 검증합니다.
*
* @throws Exception MockMvc 수행 발생할 있는 예외
*/
@Test
@DisplayName("로그아웃 성공 테스트")
void logoutSuccess() throws Exception {
// Given: 테스트에 필요한 요청 데이터와 응답 객체를 준비
LogoutRequest request = new LogoutRequest();
request.setUserId("testUser");
LogoutResponse response = LogoutResponse.builder()
.message("로그아웃이 완료되었습니다.")
.build();
given(memberService.logout(any(LogoutRequest.class))).willReturn(response);
// When & Then: API 호출 결과 검증
mockMvc.perform(post("/api/auth/logout")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value(200))
.andExpect(jsonPath("$.data.message").value("로그아웃이 완료되었습니다."));
}
/**
* 로그아웃 실패 케이스를 테스트합니다.
* 잘못된 형식의 요청 데이터로 API 호출 적절한 에러 응답이 반환되는지 검증합니다.
*
* @throws Exception MockMvc 수행 발생할 있는 예외
*/
@Test
@DisplayName("로그아웃 실패 테스트 - 잘못된 요청 형식")
void logoutFailInvalidRequest() throws Exception {
// Given: 검증에 실패하도록 필수 필드가 비어있는 요청 객체 생성
LogoutRequest request = new LogoutRequest();
// When & Then: API 호출 결과 검증
mockMvc.perform(post("/api/auth/logout")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isBadRequest());
}
}

View File

@ -0,0 +1,149 @@
package com.unicorn.lifesub.member.test.integration.repository;
import com.unicorn.lifesub.member.repository.entity.MemberEntity;
import com.unicorn.lifesub.member.repository.jpa.MemberRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
/**
* MemberRepository 통합 테스트
* TestContainers를 사용하여 실제 PostgreSQL DB와의 상호작용을 테스트합니다.
*/
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
@ActiveProfiles("integration-test")
class MemberRepositoryIntegrationTest {
@Container
static PostgreSQLContainer<?> postgreSQLContainer = new PostgreSQLContainer<>("postgres:13.2-alpine")
.withDatabaseName("member")
.withUsername("test")
.withPassword("test");
@DynamicPropertySource
static void registerPgProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl);
registry.add("spring.datasource.username", postgreSQLContainer::getUsername);
registry.add("spring.datasource.password", postgreSQLContainer::getPassword);
}
@Autowired
private MemberRepository memberRepository;
@Autowired
private TestEntityManager entityManager;
@Test
@DisplayName("회원 저장 및 조회 테스트")
void givenMemberEntity_whenSave_thenFindByUserId() {
// Given
String userId = "testUser";
Set<String> roles = new HashSet<>();
roles.add("USER");
MemberEntity member = MemberEntity.builder()
.userId(userId)
.userName("Test User")
.password("encodedPassword")
.roles(roles)
.build();
// When
entityManager.persistAndFlush(member);
entityManager.clear(); // 1차 캐시 클리어
// Then
Optional<MemberEntity> foundMember = memberRepository.findByUserId(userId);
assertThat(foundMember).isPresent();
assertThat(foundMember.get().getUserId()).isEqualTo(userId);
assertThat(foundMember.get().getUserName()).isEqualTo("Test User");
assertThat(foundMember.get().getRoles()).containsExactly("USER");
}
@Test
@DisplayName("존재하지 않는 회원 조회 테스트")
void givenNonExistentUserId_whenFindByUserId_thenReturnEmpty() {
// Given
String nonExistentUserId = "nonexistent";
// When
Optional<MemberEntity> result = memberRepository.findByUserId(nonExistentUserId);
// Then
assertThat(result).isEmpty();
}
@Test
@DisplayName("회원 정보 업데이트 테스트")
void givenExistingMember_whenUpdateInfo_thenSuccess() {
// Given
String userId = "testUser";
Set<String> roles = new HashSet<>();
roles.add("USER");
MemberEntity member = MemberEntity.builder()
.userId(userId)
.userName("Original Name")
.password("originalPassword")
.roles(roles)
.build();
entityManager.persistAndFlush(member);
entityManager.clear();
// When
MemberEntity foundMember = memberRepository.findByUserId(userId).get();
foundMember.updateUserName("Updated Name");
entityManager.persistAndFlush(foundMember);
entityManager.clear();
// Then
MemberEntity updatedMember = memberRepository.findByUserId(userId).get();
assertThat(updatedMember.getUserName()).isEqualTo("Updated Name");
}
@Test
@DisplayName("회원 삭제 테스트")
void givenExistingMember_whenDelete_thenCannotFind() {
// Given
String userId = "testUser";
Set<String> roles = new HashSet<>();
roles.add("USER");
MemberEntity member = MemberEntity.builder()
.userId(userId)
.userName("Test User")
.password("password")
.roles(roles)
.build();
entityManager.persistAndFlush(member);
entityManager.clear();
// When
MemberEntity foundMember = memberRepository.findByUserId(userId).get();
memberRepository.delete(foundMember);
entityManager.flush();
entityManager.clear();
// Then
Optional<MemberEntity> deletedMember = memberRepository.findByUserId(userId);
assertThat(deletedMember).isEmpty();
}
}

Some files were not shown because too many files have changed in this diff Show More