안녕하세요. 테스트 코드를 수강하고 있는 학생입니다. 긴 작업일 경우 트랜잭션을 걸지 말라고 하셨는데. 조회용 트랜잭션이 Repository 단에서 걸린다는 말씀을 하셨는데 Repository의 조회 로직이 수행될 때 트랜잭션이 걸리는 건가요? 뭔가 잘못 이해한거 같기도 해서 질문합니다. 그리고 @RequiredArgsConstructor @Service public class MailService { private final MailSendClient mailSendClient; private final MailSendHistoryRepository mailSendHistoryRepository; public boolean sendMail(String fromEmail, String toEmail, String subject, String content) { boolean result = mailSendClient.sendEmail(fromEmail, toEmail, subject, content); if (result) { mailSendHistoryRepository.save(MailSendHistory.builder() .fromEmail(fromEmail) .toEmail(toEmail) .subject(subject) .content(content) .build() ); return true; } return false; } } 여기서는 Transaction을 걸어줘야 하는게 맞는거 같아서. 이 부분도 궁금합니다. 요약 저는 서비스 Layer 에서 Transaction 을 걸어 db작업에서 문제가 발생했을 경우 rollback 되어야 한다고 생각했습니다. 강의에서 긴 작업들이 실제로 트랜잭션에 참여하지 않아도 되는데 -> OrderStatisticsService 에서는 CUD 작업이 아니니깐 Transaction을 안 걸어도 된다.? MailService 에서는 Transaction을 걸어줘야 하는게 아닌가요? (Create 작업 수행) 조회용 트랜잭션이 Repository 단에서 걸린다.? 뭔지 잘 모르겠습니다.
controller테스트를 할때 mockMVC를 사용하면 DB에 CRUD 작업은 수행되지 않나요? 디버깅을 해보면 각 Layer별로 동작이 수행되는거 같은데 DB접근하여 데이터를 가져오는 부분에서는 null이 계속 나오네요(MyBatis 사용중). 또 만약 실제 프로덕션 controller처럼 모든 동작이 수행된다면 왜 "하위 Layer를 모두 mocking처리" 라고 표현하시는지 궁금합니다.
외래키 사용을 지양하라는 내용이 있어서 링크된 글을 읽어봤는데 궁금증이 있습니다. 외래키를 지양한다면 PK 값을 다른 테이블에 넣으면서 그 값으로 조인을 사용하는건가요? 외래키를 지양했을 때 성능상의 이점은 알겠는데 결국 데이터 정합성 부분에서 문제가 발생합니다. RDB에서 데이터 정합성이 깨지면 사용하는 의미가 없다고 하는데 이부분에선 어떻게 생각하시나요? 외래키를 안쓸경우 JPA에서 ManyToOne같은 메소드도 사용하지 않는건가요? 그리고 해당 주장에 대해 반박하는 아래의 링크도 있는데 이 의견은 어떠신가요? https://gdsc-university-of-seoul.github.io/foreign-key/
질문있습니다. const modelListData = ['model1', 'model2', 'model3'] const [rowData, setRowData] = useState([]) useEffect(() => { setRowData(modelListData) }, [modelListData]) 위 처럼 작성을 한 후에 테스트를 돌리면 그냥 터미널이 멈춰 버립니다... 그런데 setRowData(modelListData)이걸 주석처리 하거나 배열이 아닌 타입의 값을 넣을 경우에는 테스트가 제대로 동작합니다. 혹시 test코드에 뭔가를 작성을 해주어야 할까요? ㅠㅠ 테스트 코드는 아래처럼 작성하고 돌려보았습니다. describe('모델리스트 컴포넌트 및 기능 테스트', () => { test('테스트 왜 안됨?', () => { render(<ModelList />) }) }) 그런데 터미널은 여기서 아무리 기다려도 다음으로 넘어가지 않습니다. 단 setRowData에 배열이 아닌 타입의 값을 넣을 경우에는 무리없이 잘돌아갑니다 ㅜㅜ RERUN src/modelManager/components/ModelList.tsx x2 · src/__test__/modelList.test.tsx (1) · 모델리스트 컴포넌트 및 기능 테스트 (1) · 테스트 왜 안됨?
안녕하세요. 현재 섹션 5까지 수강을 하고 헷갈리는 것이 있어 질문 남기게 되었습니다. 섹션 5에서 3개의 레이어에 대한 테스트를 진행하는 데 이 테스트들은 단위 테스트인지 통합 테스트인지 헷갈립니다. @SpringBootTest 어노테이션을 사용하는 것으로 봐서는 스프링 빈을 전부 로드하는 통합테스트 같기도 하면서, @WebMvcTest 어노테이션을 사용하는 것을 봤을 때는 다른 레이어와 독립적인 테스트를 진행하는 것 같아 단위테스트 같은 것 같다고 생각했습니다. 이번 섹션에서 진행한 테스트는 어떤 종류의 테스트인가요? 만약 단위(혹은 통합)테스트라면 다른 종류에 있는 테스트는 어떻게 진행해야 하는지, 아니면 이 테스트만으로 충분하지 궁금합니다.
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요! 먼저 유사한 질문이 있었는지 검색해 보세요. 서로 예의를 지키며 존중하는 문화를 만들어가요. 현재 자바 백엔드 개발자입니다. 현재 마이바티스로 테스트 코드를 짜려고하는데 검증할 쿼리는 어떤 테이블의 특정 버전의 가장 높은 버전을 가져오는 쿼리로 그 특정버전으로 정렬을 시키고 top(1)을 사용해서 가져오게하는 쿼리로 짜놓은 상태입니다. 그러면 이걸 테스트를 하려고하면 셀렉트 쿼리를 하나 더짜서 그 특정버전에 max()를 사용해서 값으로 가져온 후 검증을 하는 방법이 떠오르는데요 그러면 이런 또하나의 쿼리가 생기는데 또하나의 쿼리가 잘 못 된다면 그 테스트의 경우가 잘못되는것을 말하는데 이런 상황에서 어떻게 하셨는지 궁금합니다
혹시나 저와 같은 이슈를 만나셨을 분이 있으실까봐 글을 남깁니다. 강의 36:36 에서 강사님께서 teardown 을 정의해주실 때 @AfterEach 를 사용해서 매 테스트가 종료될때마다 db 를 깔끔하게 지워주도록 정의해주셨습니다. 해당 클래스( ProductServiceTest.class ) 에서 실행할 때는 문제가 되지 않고 정상적으로 작동을 합니다. 그러나 다른 테스트(ex, OrderServiceTest.class ) 에서는 @BeforeEach 를 사용해서 teardown 을 구현했는데 이 때문에 간극이 생겨 전체 테스트 를 돌렸을때 ProductServiceTest.class 에서 에러 가 발생합니다. 따라서 @BeforeEach 로 변경하여서 해결할 수 있었습니다.
회원가입은 되는데 로그인 시도 시 에러 뜨고 그전에 에러 메시지에는 아래와 같이 나왔습니다. 어느 부분에서 잘못된것일까여.s pringframework.security. authentication.InternalAuthenticationServiceException: 인증실패 at s hop.mtcoding.bank. config.auth.LoginService.lambda$loadUserByUsername$0(L oginService.java:22) at java.base/java.util.Optional.orElseThrow(O ptional.java:408) at s hop.mtcoding.bank. config.auth.LoginService.loadUserByUsername(L oginService.java:21) at o rg.springframework.security. authentication.dao.DaoAuthenticationProvider.retrieveUser(D aoAuthenticationProvider.java:94) at o rg.springframework.security. authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(A bstractUserDetailsAuthenticationProvider.java:133) at o rg.springframework.security. authentication.ProviderManager.authenticate(P roviderManager.java:182) at o rg.springframework.security. authentication.ProviderManager.authenticate(P roviderManager.java:201) at s hop.mtcoding.bank. config.jwt.JwtAuthenticationFilter.attemptAuthentication(J wtAuthenticationFilter.java:50) at o rg.springframework.security. web.authentication.AbstractAuthenticationProcessingFilter.doFilter(A bstractAuthenticationProcessingFilter.java:227) at o rg.springframework.security. web.authentication.AbstractAuthenticationProcessingFilter.doFilter(A bstractAuthenticationProcessingFilter.java:217) at o rg.springframework.security. web.FilterChainProxy$VirtualFilterChain.doFilter(F ilterChainProxy.java:346) at o rg.springframework.security. web.authentication.logout.LogoutFilter.doFilter(L ogoutFilter.java:103) at o rg.springframework.security. web.authentication.logout.LogoutFilter.doFilter(L ogoutFilter.java:89) at o rg.springframework.security. web.FilterChainProxy$VirtualFilterChain.doFilter(F ilterChainProxy.java:346) at org.springframework.web.filter.CorsFilter.doFilterInternal(C orsFilter.java:91) at org.springframework.web.filter.OncePerRequestFilter.doFilter(O ncePerRequestFilter.java:117) at o rg.springframework.security. web.FilterChainProxy$VirtualFilterChain.doFilter(F ilterChainProxy.java:346) at o rg.springframework.security. web.header.HeaderWriterFilter.doHeadersAfter(H eaderWriterFilter.java:90) at o rg.springframework.security. web.header.HeaderWriterFilter.doFilterInternal(H eaderWriterFilter.java:75)
안녕하세요. 현재 섹션 3 수강 중인 수강생입니다. todo App을 만들고 있는데, X 버튼 구현하는 부분에서 onClick 이벤트 발생 시 작동하는 함수를 삽입해주는 부분인데요. onClick => {handleClick(data.id)} 이렇게 입력하니 웹페이지가 제대로 동작하지 않고, 아래처럼 화살표 함수로 바꿔주니 정상적으로 동작합니다. <button onClick={() => handleClick(data.id)}> x </button> 찾아보니 함수명으로 넣어주는 경우는 렌더링 시 함수가 바로 실행되고 click 이벤트 발생 시엔 함수의 반환값이 중괄호 안에 들어간다고 하고, 화살표 함수로 넣어줄 경우 의도한대로 click이벤트 발생 시에 함수가 실행된다는 걸 알게됐는데요, 이런 부분은 리액트 동작 원리 상 이렇게 되는거니 그냥 받아들이면 될까요? 아니면 제가 js 문법에 대해 이해가 부족해서 이해가 안가는 걸까요...? 추가적으로, 그렇다면 리액트에서 이벤트리스너 함수를 넣을 때는 무조건 화살표 함수로 넣는게 맞는건가요?
예시 코드대로 카프카 테스트를 실행하면 잘 성공합니다. 그런데 다른 통합테스트들과 같이 실행시키면 실패합니다. 로그를 보면 잘 실행되고 문제도 없는데 process메서드를 잘 실행 했음에도 불구하고 수행되지 않았다고 나오는거 같습니다. @SlowTest public void kafkaSendAndConsumeTest() { String topic = "test-topic"; String expectValue = "expect-value"; kafkaProducerService.send(topic, expectValue); var stringCaptor = ArgumentCaptor.forClass(String.class); System.out.println("-----------mock-----------start"); Mockito.verify(kafkaConsumerService, Mockito.timeout(5000).times(1)) .process(stringCaptor.capture()); System.out.println("-----------mock-----------finish"); Assertions.assertEquals(expectValue, stringCaptor.getValue()); } 혹시 관련 문제에 대해 아실까요? ㅠㅠ
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요! 먼저 유사한 질문이 있었는지 검색해 보세요. 서로 예의를 지키며 존중하는 문화를 만들어가요. 강의 잘듣고 있습니다. persistenceLayer 계층 테스트에서 repository 를 테스트할때 Optional<Entity> 형태로 반환하는 함수를 테스트한다고 할때 어떤식으로 테스트를 작성해주어야 되나요? 예를 들어 특정 id를 가진 멤버를 조회한다고 하면 반환값이 Optional<Member>가 될텐데 무조건 찾는 테스트를 한다면 그냥 get()을 붙여서 Optional이 아닌 객체로 꺼내도 되나요?