-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: PasswordEncoder 변경 및 DirtiesContext 삭제 #429
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
크게 말씀드릴 부분이 안보이네요!
파워가 구현해주신 내용은 1.0.0 버전까지 적용하고,
1.1.0 버전으로 업그레이드한 거는 self 회원 가입 기능을 제거
하는 건 어떨지 제안합니다~
추가로 질문 주신 부분에 대해서만 제 의견 전해드릴게용!
Q. data.sql 이거 필요할까요?
현재 테스트에서 사용되지 않는다면 굳이 필요 없어보이네요!
현재 컨트롤러 테스트가 인수테스트 형식으로 되어있어서 굳이 필요없어 보이기도 하는데요.
나중에 필요하게 되면 ControllerTest에서 beforeEach에 더미 데이터를 넣어줄지
, data.sql에서 더미 데이터를 넣어줄지
한번 논의해보면 좋을 것 같네요!
Q. 도메인 서비스 위치
저는 DigginRoomPasswordEncoder만 member 쪽에 두면 좋을 것 같아요!
파워께서 PasswordEncoder를 인터페이스로 분리하신 이유가 추후에 security를 사용하게 될 때 변경 사항을 최소화하는 거로 생각했어요. 그래서 PasswordEncoder는 현재 패키지에 그대로 두고 구현체만 member로 가져와도 괜찮지 않나 생각합니다! 👍
고생하셨습니당
테스트에 허덕이는 제 hp를 살리셨어요
@AfterEach | ||
public void afterEach() { | ||
final List<String> truncateQueries = getTruncateQueries(jdbcTemplate); | ||
truncateTables(jdbcTemplate, truncateQueries); | ||
} | ||
|
||
private List<String> getTruncateQueries(final JdbcTemplate jdbcTemplate) { | ||
return jdbcTemplate.queryForList( | ||
"SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ' RESTART IDENTITY;') AS q " | ||
+ "FROM INFORMATION_SCHEMA.TABLES " | ||
+ "WHERE TABLE_SCHEMA = 'PUBLIC'", String.class); | ||
} | ||
|
||
private void truncateTables(final JdbcTemplate jdbcTemplate, final List<String> truncateQueries) { | ||
execute(jdbcTemplate, "SET REFERENTIAL_INTEGRITY FALSE"); | ||
truncateQueries.forEach(v -> execute(jdbcTemplate, v)); | ||
execute(jdbcTemplate, "SET REFERENTIAL_INTEGRITY TRUE"); | ||
} | ||
|
||
private void execute(final JdbcTemplate jdbcTemplate, final String query) { | ||
jdbcTemplate.execute(query); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이거 저도 어제 이 방법이 생각나서 담주 쯤에 한번 작업해보려고 했는데 좋네용 bb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생했습니다 파워!
덕분에 도메인 서비스가 무엇인지 계속해서 감이 잘 잡혀가는거 같아요
추가적으로 스프링 시큐리티가 제공하는 PasswordEncoder
인터페이스도 배워가네요!
데이터베이스 초기화 관련해서 리뷰 남겼습니다!
확인해보시구 의견주세용
|
||
@AfterEach | ||
public void afterEach() { | ||
final List<String> truncateQueries = getTruncateQueries(jdbcTemplate); | ||
truncateTables(jdbcTemplate, truncateQueries); | ||
} | ||
|
||
private List<String> getTruncateQueries(final JdbcTemplate jdbcTemplate) { | ||
return jdbcTemplate.queryForList( | ||
"SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ' RESTART IDENTITY;') AS q " | ||
+ "FROM INFORMATION_SCHEMA.TABLES " | ||
+ "WHERE TABLE_SCHEMA = 'PUBLIC'", String.class); | ||
} | ||
|
||
private void truncateTables(final JdbcTemplate jdbcTemplate, final List<String> truncateQueries) { | ||
execute(jdbcTemplate, "SET REFERENTIAL_INTEGRITY FALSE"); | ||
truncateQueries.forEach(v -> execute(jdbcTemplate, v)); | ||
execute(jdbcTemplate, "SET REFERENTIAL_INTEGRITY TRUE"); | ||
} | ||
|
||
private void execute(final JdbcTemplate jdbcTemplate, final String query) { | ||
jdbcTemplate.execute(query); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Controller 테스트 이외에서도 사용할 수 있도록 Junit Extenstion 등록해보면 어떨까요??
BeforeEachCallback
은 매 @BeforeEach
이전에 수행됩니다!
@Component
public class DatabaseCleaner {
@Autowired
private EntityManager entityManager;
private List<String> tableNames;
@PostConstruct
private void setUpDatabaseTableNames() {
this.tableNames = getTableNames();
}
private List<String> getTableNames() {
return getTableMetaData().stream().map(this::getTableName).toList();
}
@SuppressWarnings("unchecked")
private List<Object[]> getTableMetaData() {
return entityManager.createNativeQuery("SHOW TABLES").getResultList();
}
private String getTableName(final Object[] tableInfos) {
return (String) tableInfos[0];
}
@Transactional
public void clear() {
executeQuery("SET REFERENTIAL_INTEGRITY FALSE;");
tableNames.forEach(tableName -> executeQuery("TRUNCATE TABLE " + tableName + " RESTART IDENTITY;"));
executeQuery("SET REFERENTIAL_INTEGRITY TRUE;");
}
private void executeQuery(final String query) {
entityManager.createNativeQuery(query).executeUpdate();
}
}
public class DatabaseCleanerExtension implements BeforeEachCallback {
@Override
public void beforeEach(final ExtensionContext context) throws Exception {
SpringExtension.getApplicationContext(context)
.getBean(DatabaseCleaner.class)
.clear();
}
}
위와 같이 extension 으로 등록한 후 ExtendWith 어노테이션에 명시해서 사용할 수 있습니다!
@ExtendWith(DatabaseCleanerExtension.class)
@DisplayNameGeneration(ReplaceUnderscores.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public abstract class ControllerTest {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생했씁니다 파워~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
리뷰하려고 했더니 실시간으로 변하네요 ㅎㅎ
나중에는 '멤버 저장' 자체를 하나의 도메인 서비스로 만들수도 있을 것 같네요.
고생하셨습니다
* feat: PasswordEncoder 인터페이스 분리 * test: DirtiesContext 삭제 * refactor: 테스트용 데이터베이스 초기화 객체 추출 * refactor: 남아있는 DirtContext 삭제 * remove: 사용하지 않는 클래스 삭제 --------- Co-authored-by: songusika <sws981202@gmail.com>
관련 이슈번호
작업 사항
PasswordEncoder 변경
PasswordEncoder를 도메인 서비스로 보고 변경 했습니다.
참고
현재 PasswordEncoder가 도메인안에있어서 Spring Security로 PasswordEncoder가 변경되는 상황에서 유연하게 대처하기 힘들기 때문에 수정해봤습니다.
이런느낌
DirtiesContext 삭제
Controller에서 DirtiesContext 대신 매 테스트마다 Database만 TRUNCATE 하도록 변경했습니다.
16초->6초 개선
논의 해보고싶은거
data.sql 이거 필요할까요?
테스트는 data.sql 없이 테스트 가능한 상황이에요
만약에 data.sql이 필요하다면 로컬에서 테스트해보기위함일꺼같은데
후자로 필요하다면 더미값을 조금더 추가하면 좋을듯하네요
도메인 서비스 위치
도메인 서비스면 구현체 DigginRoomPasswordEncoder 얘만 member 쪽으로 옮기면 좋을까요
아니면 DigginRoomPasswordEncoder, PasswordEncoder, HashAlgorithm 모든 코드를 member쪽으로 옮기는게 좋을까요
패스워드 암호화하는과정들을 전부 비즈니스로직으로 보고 member쪽으로 옮겨도 될거같네요