문제 상황 문제상황을 재현하기 위해 먼저 Person 클래스를 하나 생성하겠습니다. class Person { fun isDeveloper(name: String, age: Int): Boolean { return true // 무조건 true를 반환 } } 만약 isDeveloper()의 파라미터를 Stub할때 동적인 값을 허용할려면 아래과 같이 사용할 것입니다. val mock = mock(Person::class.java) `when`(mock.isDeveloper(anyString(), anyInt())).thenReturn(true) 여기서 추가로 name은 "charlie"이지만 age값은 동적으로 받고 싶은 경우에 문제가 발생합니다. // NullPointerException 발생 `when..
문제 상황 mockito-kotlin을 이용해 findByIdOrNull() 메서드를 모킹해서 테스트 코드를 작성중이었다. @Test fun `쿠폰 한건 조회`() { whenever(mockCouponRepository.findByIdOrNull(1L)).thenReturn( Coupon(id = 1L, type = CouponType.PERCENT, amount = 10, startAt = LocalDate.of(2023, 4, 12), endAt = LocalDate.of(2023, 4, 12)) ) val result = couponService.getOne(1L) assertThat(result.type).isEqualTo(CouponType.PERCENT) assertThat(result.am..
문제 상황 먼저 저의 상황은 코틀린(kotlin) 언어로 mockito를 사용하는 환경에서 발생하였습니다. 코틀린언어가 아닌 다른 언어를 사용하셨다면 저의 케이스와 다른 경우일 확률이 높습니다. mockito의 Argument matchers의 eq() 메서드를 사용시에 문제가 발생하였다. 문제 상황을 가정하기 위해 먼저 Person 클래스를 하나 생성하자 class Person { fun isDeveloper(name: String, age: Int): Boolean { return true } } Argument matchers를 이용해 name이 "charlie"이고 age는 any()로 스텁(stub) 진행 하였다. // NullPointerException 발생 `when`(mock.isDeve..
인텔리제이에서 코드를 작성하다보면 같은 단어를 한번에 수정하게 되는 경우가 종종있습니다. 이럴때 유용하게 사용할 수 있는 단축키를 소개합니다. 1. 같은 단어 일괄 선택 (Multiple selection) 단축키 : ⌘⇧G (Command + Control + G) 실행 순서 변경하고 싶은 단어에 커서를 이동시킨다 ⌘ ⇧ G 단축키를 누른다 변경하고 싶은 단어를 입력한다 단어 변경이 완료되면 esc를 누른다. 2. 같은 단어 연속적으로 선택 (Consecutive Multiple selection) 단축키 : ⌘G (Command + G) 실행 순서 변경하고 싶은 단어에 커서를 이동시킨다 ⌘ G 를 통해 변경할 단어들을 선택한다. 변경하고 싶은 단어를 입력한다. 단어 변경이 완료되면 esc를 누른다. ..
Error 상황 프로젝트 환경 설정 application.yml spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/awss3?serverTimezone=UTC&characterEncoding=UTF-8 username: root password: 1234 jpa: database-platform: org.hibernate.dialect.MySQL5InnoDBDialect open-in-view: false show-sql: true hibernate: format_sql: true ddl-auto: create JPA관련 테스트를 하기 위해 @DataJpaTest를 이용해서 테스트를..
문제 기존에 프로젝트를 진행할때 클라이언트로 부터 오는 요청데이터를 Bean Validation한후 Error가 있다면 bindingResult에 에러 내용을 담아 다시 넘겨주었습니다. 그런데 댓글 작성을 구현할때 요청데이터를 validation(유효성 검사)를 한뒤 bindingResult에 에러내용을 담아 Json응답으로 반환하니 에러메시지가 의도와 다르게 전달되는것을 확인할 수 있었습니다. 댓글 작성 소스 ReplyRequest 요청 DTO @Getter @Setter public class ReplyRequest { @NotNull private Long bno; @NotEmpty @Length(min = 4) private String comment_content; } error.properti..
프로젝트를 진행하면서 파일들이 하나둘씩 늘어남에 따라 패키지 구조를 바꿔야겠다는 생각이 들었습니다. 먼저 저의 패키지 구조를 먼저 보여드리고 어떻게 변경하였는지 설명하겠습니다. 계층형 main ├── java │ └── stude │ └── chalieZip │ ├── config │ ├── controller │ ├── service │ ├── repository │ ├── dto │ ├── entity │ ├── interceptor │ └── CharlieZipApplicaton.java └── resources └── application.properties 저의 패키지 구조는 계층형 구조로 각 계층을 대표하는 디렉터리 기준으로 코드들이 구성됩니다. 처음에 프로젝트를 시작할때는 매우 작게 규모로 ..
CharlieZip 프로젝트를 진행하면서, 로그인 기능이 구현하고 나니 많은 부분에 로그인여부를 체크해야하는 일이 발생하였습니다. 그로 인해, 많은 코드 중복이 발생하게 되었고, 추후 추가나 변경이 있을시 일일히 찾아가며 수정을 해야하기 때문에 유지보수성이 매우 떨어질 수 있습니다. 그래서 로그인 여부 로직을 한 곳으로 분리하여 관리하도록 리팩토링을 진행하였습니다. AOP VS Interceptor 애플리케이션 여러로직에서 공통으로 관심이 있는것을 공통 관심사(cross-cutting concern)라고 합니다. 이러한 공통 관심사는 스프링의 AOP로도 해결할 수 있지만, 저의 공통 관심사는 로그인 여부이고 이는 웹과 관련된 공통 관심사입니다. charlieZip 프로젝트는 rest api가 아닌 뷰 템..
- Total
- Today
- Yesterday
- trailing comma
- mockK
- kotlin
- ExitStatus
- assertj
- IntelliJ
- autoconfigure
- JUnit5
- Collection
- java
- datasource
- 클린 아키텍처
- Spring Batch
- A레코드
- GSLB
- prinicipal
- Parameterized
- Mockito
- AWS INDUSTRY WEEK
- WrongTypeOfReturnValue
- Spring
- Stream
- spring data jpa
- 시나리오 테스트
- BatchStatus
- test
- meta-data
- asSequence
- mockito-kotlin
- scenario test
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |