묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Practical Testing: 실용적인 테스트 가이드
TDD질문
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요 강의를 듣던중 의문이 생겨 질문드립니다.TDD 빨간불을 보고 (강의 6분 쯤) 초록불을 만드는 과정에서 return 8500을 하셨는데이렇게 초록불을 만드는 게 맞나요?? 오히려 무슨 테스트를 수정해야하는 지 헷갈릴 거 같은데제가 이해한 초록불을 만드는 과정은 변수명, JPA를 사용한다면 N+1 문제 등 아예 신경안쓰고 초록불을 만들고 위 문제들을 수정해 가는 과정으로 생각했는데..
-
미해결Practical Testing: 실용적인 테스트 가이드
createOrder 변경
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요 강의를 듣다가 의문점이 생겨 질문드립니다.createOrder의 test를 구현하기 위해 LocalTime을 인자로 받게 변경했는데 결국 test를 위해 비지니스 로직을 수정을 하는 과정이 너무 짜치는데 다른 방법은 없을까요? 강의 뒤쪽에 나오는 걸까요?
-
해결됨Practical Testing: 실용적인 테스트 가이드
"테스트 케이스 세분화하기" 강의 화면이 안나옵니다
다른 강의는 잘 나오는데 테스트 케이스 세분화하기 강의만 화면이 까맣게 나옵니다. 저만 그럴까요?Arc 브라우저에서 수강하다가 크롬 브라우저에서도 확인해봤는데 똑같이 화면이 안나옵니다. UPDATE 1: "테스트 케이스 세분화하기" 부터 화면이 안나오는 것 같네요.UPDATE 2: 크롬에서 하드웨어 가속 기능을 끄니까 정상적으로 화면이 나옵니다. 왜 기능을 꺼야하는건지 이유를 알고 싶긴하네요.
-
미해결Practical Testing: 실용적인 테스트 가이드
컨트롤러 테스트 시 POST시 Mockito.when() 처리에서 질문드립니다.
안녕하세요 제가 좀 더 응용해서 post 요청 시에 Mockito.when()과 접목시킨 테스트를 진행해봣는데 이 과정에서 질문이 있어 질문 드립니다. 예시 코드는 다음과 같습니다.void signUpTest() throws Exception { //given var memberResponse = new MemberResponse(MEMBER_ID, MEMBER_EMAIL); var signUpRequest = new SignUpRequest(MEMBER_EMAIL, "password"); //when when(memberFacadeService.signUp(signUpRequest)) .thenReturn(memberResponse); //then mockMvc.perform( post("/api/v1/members/signUp") .content(OBJECT_MAPPER.writeValueAsString(signUpRequest)) .contentType(MediaType.APPLICATION_JSON) ) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$.id").value(MEMBER_ID)) .andExpect(jsonPath("$.email").value(MEMBER_EMAIL)); }이 코드 시에 문제가 발생합니다. 문제는 java.lang.AssertionError: No value at JSON path "$.id"이거입니다. 근데, 이 코드를 아래와 같이 바꾸면 에러가 발생하지 않습니다.void signUpTest() throws Exception { //given var memberResponse = new MemberResponse(MEMBER_ID, MEMBER_EMAIL); var signUpRequest = new SignUpRequest(MEMBER_EMAIL, "password"); //when when(memberFacadeService.signUp(any(SignUpRequest.class))) .thenReturn(memberResponse); //then mockMvc.perform( post("/api/v1/members/signUp") .content(objectMapper.writeValueAsString(signUpRequest)) .contentType(MediaType.APPLICATION_JSON) ) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$.id").value(MEMBER_ID)) .andExpect(jsonPath("$.email").value(MEMBER_EMAIL)); }위와 아래의 차이는 requestBody에 들어가는 SignUpRequest 클래스를 mockBean처리 된 memberFacadeService의 when 처리 시에 해당 클래스를 any()로 처리하나 안처리하나의 차이입니다. 제가 예상하기에는 mockMvc에서 .content(objectMapper.writeValueAsString(signUpRequest)) 로 이렇게 처리했기 때문에 해당 로직에 들어가는 memberFacadeService 클래스의 signUp 매개변수로 들어가는 SignUpRequest가 제가 위에서 선언한 signUpRequest와 다르기 때문에 발생하는 문제라고 생각합니다. 이 이해가 맞는지에 대한 질문과 post요청에서는 다 이렇게 any()처리를 해야되는지 궁금합니다.
-
해결됨Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
테스트 메서드 마다 Environment variables 설정이 불편...
강의시나리오 대로 진행하다보니 살짝 불편한 부분이 있어서..(어쩜 중간에 코멘트가 있었는데 놓친것일 수도..)서비스 설정 중 메일발송 설정 정보를 실행속성으로 구성하는데테스트도 동일하게 구성하다보니(test-application.properties )Intellij >Edit Configurations > JUnit 실행인스턴스 별 Environment variables 를 설정해줘야 실행이 되는듯 합니다. 테스트 메서드를 만들때마다 실행인스턴스를 설정해야하는게 불편해서 그냥 메일발송 설정을 test-application.properties 에 하드코딩하고 진행해봅니다.(혹시.. 다른 더 스마트한 방법이 있을까? Intellij ? spring?) [확인1]'테스트 추가하기: h2를 이용한 repository 테스트' 강의 1:16초를 보면 git에서 받은 application.properties 파일과 강의의 소스가 다른것 으로 보입니다. Environment variables 에서 설정한 속성이 없어서 해당 강의에서는 불편함 없이 진행된 것 으로 이해했습니다. [확인2] 그런데'토이 프로젝트 살펴보기' 강의 7:42 에 확인되는 설정정보는 git 소스와 동일하것으로 확인됩니다. 강의를 훑어볼때는 그냥 넘어갔는데, 따라하며 보니 눈에 밟히는게 좀 있네요. 제가 놓친부분이라면 양해 바라며, 시나리오 상 연결부분이 필요한 내용이면 코멘트 부탁드립니다. 저와 같이 길잃은 양들을 살펴주소서~[git 설정파일]
-
미해결Practical Testing: 실용적인 테스트 가이드
테스트할 때 Auditing 없이 원하는 날짜를 설정할 수 잇을까요?
공부삼아서 과제 프로젝트에 테스트를 도입하다가 궁금한 게 잇어서 질문드립니다. 거래내역 조회를 구현할 때 2024-05-30 같은 거래가 발생할 날짜는 auditing, @CreatedAt 통해 저장된 createdAt에서 가져오도록 구현했습니다. (디자인과 달리, 최근 거래일수록 위로 오도록 변경되었습니다) 구현이 끝난 뒤, 테스트할 때 createAt을 임의로 변경하기 위해 BaseEntity의 private를 protected, 그리고 createdAt을 변경하는 메서드를 추가햇습니다. (이게 맞는 접근인지는 잘 모르겟네요... 할 때에도 이렇게 해도 되나? 라는 의문이 계속 들엇습니다...)@DisplayName("유저의 계좌 내역을 불러올 수 있다.") @Test void getUserStatements() { // given (6/5 18:00) LocalDateTime now = LocalDateTime.of(2024, 6, 5, 18, 0, 0); User u1 = User.of("test1", "id1", "pw"); User u2 = User.of("test2", "id2", "pw"); List<User> users = userRepository.saveAll(List.of(u1, u2)); User loginUser = users.get(0); User notLoginUser = users.get(1); Account a1 = Account.of("111-222-3333", 1000, loginUser); Account a2 = Account.of("111-222-3334", 2000, notLoginUser); List<Account> accounts = accountRepository.saveAll(List.of(a1, a2)); Account loginUserAccount = accounts.get(0); Account notLoginUserAccount = accounts.get(1); // 자신 계좌로 입금 (조회 대상), 6/5 발생 Statement s1 = createStatementForTest(loginUserAccount, loginUserAccount, 100, DEPOSIT); // 자신 계좌에서 출금 (조회 대상), 6/6 발생 Statement s2 = createStatementForTest(loginUserAccount, loginUserAccount, 200, WITHDRAW); // 자신 계좌에서 타 계좌로 이체 (조회 대상), 6/7 발생 Statement s3 = createStatementForTest(loginUserAccount, notLoginUserAccount, 300, TRANSFER); // 타 계좌에서 자신 계좌로 이체 (조회 대상), 6/8 발생 Statement s4 = createStatementForTest(notLoginUserAccount, loginUserAccount, 400, TRANSFER); // 타 계좌에서 타 계좌로 출금 (조회 대상 X), 6/9 발생 Statement s5 = createStatementForTest(notLoginUserAccount, notLoginUserAccount, 50000, WITHDRAW); statementRepository.saveAll(List.of(s1, s2, s3, s4, s5)); // when StatementResponse userStatement = statementService.getUserStatements(loginUser); // then assertThat(userStatement.getStatementInfos()).as("거래 이력을 조회할 수 있다.").hasSize(4) .extracting("amount", "type") .containsExactly( tuple(400, "이체"), tuple(-300, "이체"), tuple(-200, "출금"), tuple(100, "입금") ); assertThat(userStatement.getBalance()).as("계좌 잔액을 조회할 수 있다.").isEqualTo(1000); }(위 테스트 코드는 시간 설정 및 검증 코드를 제거한 테스트입니다.) 위 메서드와 plusDays() 통해 시간 설정 후, extracting에 "date" (createdAt에 yyyy-MM-dd를 적용시켜 String 형태로 저장) 를 추가해서 확인했을 때에는 의도한 대로 2024-06-08, 2024-06-07, 2024-06-06, 2024-06-05가 아닌, 전부 테스트를 실행한 시간으로(2024-06-05) 나오는 걸 확인했습니다. 일단은 date를 검증하는 로직을 빼고 테스트를 통과시켰고, postman에서 입금/출금/이체 등 실시 후 조회했을 때에도 의도한 대로 최근 거래가 위로 오도록, 날짜 형식도 의도한 대로 나온 것도 볼 수 있었습니다. 하지만 이 date를 postman이 아닌, auditing 없이 임의로 날짜를 설정한 후 테스트해 확인해보고 싶은데, 이 경우에는 어떻게 하면 될까요? auditing 잇는 상태로도 가능하다면 알려주시면 감사하겟습니다! 아래는 BaseEntity와 거래 내역을 저장하는 Statement Entity 코드입니다@Getter @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public abstract class BaseEntity{ @CreatedDate private LocalDateTime createdDate; }import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import java.time.LocalDate; import java.time.LocalDateTime; import static jakarta.persistence.EnumType.*; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Statement extends BaseEntity{ @Id @GeneratedValue(strategy= GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="from_account") private Account from; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="to_account") private Account to; private int amount; @Enumerated(STRING) private TransactionType type; @Builder private Statement(Account from, Account to, int amount, transactionType type) { this.from = from; this.to = to; this.amount = amount; this.type = type; } public static Statement of(Account from, Account to, int amount, transactionType type){ return Statement.builder() .from(from) .to(to) .amount(amount) .type(type) .build(); } } 긴 글 읽어주셔서 감사합니다~
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
CertificationService의 테스트에서 FakerMailSender를 이용하는 부분에서 질문이 있습니다.
해당 방식은 FakerMailSender에 결국 테스트 의존성이생기게 된다고 생각하는데요.현재 코드는 단순해서 개발자가 테스트 코드 수정시 확인할 부분이 없지만, 추후 객체의 구조가 변경되거나, 규칙이 추가 - 변경된다면 모든 테스트 코드의 요구사항에 맞도록 Faker객체의 구현 내용도 함께 변경되어야 할것같습니다. 하지만 항상 모든 테스트의 요구사항을 알기는 쉽지만은 않을것같은데요.이러한 불편함을 극복하기 위한 방법이 있을까요?
-
해결됨Practical Testing: 실용적인 테스트 가이드
jpaRepository 에서 update 메서드 테스트 질문 드립니다.
jpaRepository에서 update 관련 메서드를 테스트하던 중 고민이 생겼습니다.update로 변경한 결과가 DB가 아닌, 영속성 컨텍스트에만 반영이 되어서 수정된 값을 확인하기 위해 find()메서드로 저장된 객체를 불러오면 수정한 것과 다른 원본 결과가 출력됩니다.이 문제를 해결하기 위해 두 가지 방법을 생각해보았습니다.하나는 @Modifying 애노테이션에 clearAutomatically = true 라는 옵션을 달아주는 방법이었는데, 이 방식은 테스트를 위해 프로덕션 코드를 수정하기도 하고 성능에 문제가 발생해서 제외하였고다른 하나는 테스트 코드에 EntityManager를 이용해 강제로 flush()와 clear()를 이용해 영속성 컨텍스트를 비워주도록 하는 방법이었습니다. 이 방식도 테스트 코드가 깔끔하지 않고 더 jpa에 종속적이게 되는 것 같아서 마음에 들진 않는데 강사님은 어떤 방식으로 해결하셨는지 궁금합니다!
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
토이프로젝트 실행시 이메일 설정 부분에서 앱비밀번호 항목이 보이지 않습니다.
계정차이일 수 있겠지만, 해결방법을 찾을 수 있을까 하여 문의드립니다. 제 구글 계정은 앱비밀번호 항목이 없습니다. 혹시 다른 방법이 없을까요?
-
해결됨Do It! 장고+부트스트랩: 파이썬 웹개발의 정석
doitdjango 블로그 게시판 작동 오류
안녕하세요.요즘에 'aws lightsail 로 프로젝트 옮기기'를 듣고 있습니다.거기서 블로그 글을 참고하라고 하셔서, 블로그를 들어갔더니, 해당 블로그 게시판이 작동하지 않습니다.확인 부탁드려도 될까요? 감사합니다.
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
변경감지
도메인 모델을 추가하고 그 도메인 모델 내부에서 작업을 처리하기 때문에 변경 감지 (dirty checking) 의 기능을 사용하지 못하게 되는 거 같은데요! 이 부분은 어느정도 포기를 하는걸까요?
-
미해결실전! 스프링부트 상품-주문 API 개발로 알아보는 TDD
이 방법이 TDD가 맞나요?
안녕하세요! 강의를 드는 중 의아한 부분이 있는데요.제가 알고, 공부했던 TDD 와는 달라서 좀 의문이네요.제가 아는 TDD는 Red - Green - Refactor 사이클을 통해 테스트 코드를 작성하면서 자연스럽게 프로덕트 코드가 생성되는 방법입니다. 그 과정은 매우 세밀하고, 정말 짧은 주기로 테스트를 돌려봐야하죠. 강의에서는 프로덕트 코드를 테스트 파일에 작성하는 것으로 밖에 안 보이고 POJO 상품등록하는 로직이 완성될 때까지 테스트를 단 한 번 돌려본다는 게 의아하네요. 테스트 파일에 아무런 테스트 없이 내부 클래스로 프로덕트 코드를 작성하고 다 만들어지면 그 클래스를 옮기는 게 TDD가 맞나요? 이 정도 TDD라면 프로덕트 코드 먼저 만들고 단위 테스트 작성하는 것과 별반 차이가 없다고 느껴져요.제가 순수 자바로만 TDD를 공부했기 때문에 스프링 부트에서 어떻게 하는 지 모르는 걸 수도 있는데, TDD 근간이 달라지는 것 같아 정말 순수하게 궁금합니다.
-
미해결Practical Testing: 실용적인 테스트 가이드
access token의 경우 테스트 코드에서 어떻게 처리해야되나요?
안녕하세요. 현재 강의 잘 수강하고 있습니다.현재 거의 모든 controller에서 access token을 받아서 사용하고 있습니다.토큰의 경우 만료시간 등이 있는데 테스트 코드에서 어떻게 처리되는지 궁금합니다.저 같은 경우는 spring security 사용하지 않고, 직접 API로 Token을 발급하였습니다.예시라던지 레퍼런스가 있다면 공유 좀 부탁드려요~감사합니다.
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
CSS
영화 상세페이지 구현에서 className으로 modal_poster-img를 주니까 다른 곳에 있던 css가 적용되는데 위에 import하지 않아도 가능한건가요??
-
미해결실전! 스프링부트 상품-주문 API 개발로 알아보는 TDD
POJO로 개발했는데 비즈니스 로직을 로깅해야 할 경우, 어떻게 해야 할까요?
강의 잘 듣고 있습니다! 강의 들으면서 문득 궁금한 점이 생겼는데요. POJO로 개발했는데, 도메인 클래스 내의 비즈니스 로직을 로깅을 해야하는 경우가 실무에서 많을까요? 만약, 그런 경우가 있다면, 어떻게 해야 할지 궁금합니다. 공통된 패턴이 있다면, AOP를 사용해볼 수 있을 것 같은데, 그렇지 않은 경우, 어쩔 수 없이 도메인 모델이 로깅 프레임워크에 의존하지 않나 라는 생각이 들어서요. 로깅하고 싶은게 클래스의 메서드의 매개변수와 리턴값이 아닌 내부 로직 함수일 경우가 특히 궁금합니다. 혹시, 이런 경우는 실무에서 잘 발생하지 않아 알 필요가 없을까요?
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
local storage
저장할 때밑에 코드를 쓰면 에러가 뜹니다ㅠㅠ어떻게 해결해야하나요?const initalTodoData = localStorage.getItem("todoData") ? JSON.parse(localStorage.getItem("todoData")) : []; function App() { const [todoData, setTodoData] = useState([initalTodoData]);
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
list컴포넌트 생성하기
List 컴포넌트 생성하기에서 props로 key={data.id}를 넘겨주는데 저기서는 사용하지 않는데 넘겨주어야 하나요? 빼도 상관 없나요??
-
미해결실전! 스프링부트 상품-주문 API 개발로 알아보는 TDD
generate -> add Dependency 이 메뉴가 안보이던데, 어떻게 보이게할까요?
generate -> add Dependency 이 메뉴가 안보이던데, 어떻게 보이게할까요?
-
미해결Practical Testing: 실용적인 테스트 가이드
a 서비스에서 b 서비스를 의존하는 코드에 대한 테스트는 어떻게 해야 되나요??
안녕하세요 강사님, 궁금한게있습니다.인스타그램, 페이스북을 사용할 때 제가 쓴 게시글에 다른 사람이 댓글을 달면 알림이 생성되는데, 제가 작성한 로직에서는 CommentService에서 댓글을 작성하고 alarmService를 호출하여 알림까지 생성하는 로직입니다.이렇게 로직을 짰을 때 제가 생각한 문제점에 대한 해답을 찾고 싶습니다.1. CommentService에서 다른 Service를 의존하게 되는 것2. 댓글 작성이라는 테스트를 짤 때 댓글 작성에 초첨을 맞출 수 없고 알림까지 테스트를 작성해야 되기 떄문에 핵심 기능 외에 다른 부가적인 기능 때문에 테스트의 집중도가 떨어집니다.3. 한 트랙잭션에 묶여서 알림을 생성하는데 문제가 발생하면 댓글도 생성되지 않습니다.이러한 경우 어떤 학습을 통해 개선할 수 있는지 가르쳐주실 수 있나요?
-
해결됨부트캠프에서 알려주지 않는 것들 (리액트) 1편
코드 샌드박스 안되는거같습니다
코드 샌드박스들어가면 이런식으로 뜨는데 어떻게 해결하나요?