게시글
질문&답변
2024.11.17
강의 배운 거를 프로젝트에 적용하고 있는데 궁금한 게 있어요!
안녕하세요, yg04076 님!저는 비슷한 상황에서, 사용되는 빈도 보다는 도메인의 역할과 책임, 관심사를 더 중요하게 보고 있는데요.현재 시점에서 재활용이 되고 있지 않더라도, 관심사와 전혀 다른 유틸성 기능은 유틸 클래스로 분리하는 편이에요.다만, 미래 시점에도 외부가 아닌 특정 클래스 내에서만 쓰일 가능성이 높다고 판단한다면, 해당 클래스에 private 메서드 정도로 분리하여 두어도 크게 상관 없다고 생각합니다.저라면, 위 예시 코드에서 convertBytesToMB()는 해당 클래스에, 일반적인 Long에 대해 다루는 parseLongSafely()는 유틸 클래스로 분리할 것 같네요.감사합니다. 🙂
- 0
- 1
- 31
질문&답변
2024.11.17
정적 팩토리 메서드 사용과 toEntity 메서드에 대해 질문 있습니다.
안녕하세요, 감바스 님!우선, 정적 팩토리 메서드와 toEntity()가 반대되는 개념은 아닌 것 같아요.toEntity()에서 Product의 정적 팩토리 메서드를 사용할 수도 있으니까요.toEntity()는 말 그대로 DTO 내에서 DTO가 가진 데이터로 Entity 객체를 생성할 때 주로 붙이는 메서드명인데요. (반드시 그런 것은 아니고 관습적인 이름이라 이해해주시면 됩니다.)정적 팩토리 메서드는 이와 관계없이, 단순한 생성자 대신 객체의 생성 방식을 제한하면서 외부에 의도를 전달하기 위한 방법입니다.위와 같이 각 방법의 의도에 맞게 사용해주시면 됩니다.감사합니다. 🙂
- 0
- 2
- 35
질문&답변
2024.11.11
Integration Test Truncate
안녕하세요, skehdxhd 님!일단 그런 전제라면, 테스트를 진행하지 않고 테스트하기 더 나은 방향으로 구조를 개선한 뒤에 테스팅을 진행할 것 같습니다만..ㅎㅎ개발DB가 모두가 사용하는 공용 DB 라면, 테스트할 때마다 심혈을 기울여야 할 것 같아요.그럼에도 한번 생각해보자면, 영향도를 최소화하기 위해 테스트를 시작하기 전에 신규 테이블을 생성하고, 테스트를 진행한 후에, 해당 테이블을 truncate 처리할 것 같네요.성능 테스트도 마찬가지 입니다.(2번 조건은 사용하는 도구의 차이이기 때문에 크게 상관 없을 것 같아요.)그렇지만, 저라면 저런 환경에서 테스트를 진행하기 보다 빠르게 테스트 가능한 환경을 만드는데에 집중할 것 같아요.감사합니다. 🙂
- 0
- 1
- 37
질문&답변
2024.11.11
readOnly = true 시 jpa 동작관련
안녕하세요, 개foot 님!읽기 전용 트랜잭션에서는 변경감지(U) 뿐만 아니라 CUD 작업 모두 동작하지 않습니다.말 그대로 CRUD 중 Read 작업만 하겠다는 의미이니까요.감사합니다. 🙂
- 0
- 2
- 49
질문&답변
2024.11.11
자바 익셉션 종류도 외우시나요??
안녕하세요, 한지찬 님!외우실 필요는 없습니다. ㅎㅎ 사실 애플리케이션 내 대부분의 예외 케이스가 IllegalArgumentException 의 의미가 통하기도 하구요. (즉, 이 예외 하나만 알아도 충분)의미가 부족하다면 도메인에 맞는 커스텀 예외를 만들어서 던지는 방법을 사용하면 되기 때문에, 크게 고민하실 필요는 없습니다.감사합니다 🙂
- 0
- 2
- 50
질문&답변
2024.11.11
검증 필드의 영역
안녕하세요, 조희제 님! 만약 10개의 필드를 업데이트 한다면 모든 필드를extracting 하여 검증 해야 하나요?3~4개의 대표적인 필드만 하는게 맞을까요?말씀하신 것처럼 안정성 측면에서는 다 검증하는 것이 물론 좋으나, 전체적인 비용을 고려했을 때 검증에 충분하다고 생각하는 정도만 해도 괜찮다고 생각합니다. 컨텍스트 정보를 UserUtils로 만들고 서비스에서utils 값을 꺼내어 사용 하고 있습니다.가능한 방법입니다만, 동시성 문제가 없게 구현과 테스팅은 충분히 이루어져야 할 것 같아요.잘못해서 User ID가 꼬여버리기라도 하면 큰 문제가 생길 수도 있겠죠.그리고 Utils 라는 이름은 보통 도메인과 관련 없는 범용적인 헬퍼 메서드들을 모아놓는 클래스에 어울리기 때문에(ex. StringUtils, LocalDateTimeUtils), 다른 이름이 좀 더 좋지 않을까 합니다. 마지막 질문은 블로그에 테스트에 관해 작성 해도 괜찮을까요?강의 예제와 내용을 그대로 옮기는 수준이 아니라 요약하는 정도라면 괜찮습니다. 감사합니다. 🙂
- 0
- 2
- 49
질문&답변
2024.11.02
stock을 entity로 분류 하는 이유
안녕하세요, 조희제 님!물론 그렇게 할 수도 있고, 예제가 간단한 편이라 그렇게 관리하는 것도 가능하겠지만, 실무에서 '재고'라는 개념은 정말 많은 이해관계가 얽혀 있기에 따로 관리하는 것이 좋습니다.말씀주신 '재고가 필요 없는 상품'도 재고 정보를 가지게 되기도 하고, '재고'라는 개념과 관련된 수많은 메타 정보가 같이 저장되어야 하기도 합니다.'상품' 이라는 개념도 정말 많은 데이터를 가지게 될 것이고요.동시성 문제도 고려되어야 할텐데, 상품과 재고가 같이 관리되는 대용량 테이블에 이러한 것들을 모두 적용하는 것은 상당히 부담이 되겠죠.정리하면, 상품도 복잡한 도메인일 뿐더러 재고 자체만 해도 고려해야 할 사항들이 많기 때문에, 상품의 전체 데이터에 재고를 같이 넣는 것 보다는 별도로 관리하는 것이 더 좋다는 의견입니다.도움이 되셨기를 바랍니다.감사합니다 🙂
- 0
- 1
- 62
질문&답변
2024.11.02
private 메서드를 public으로 바꾸면 어떤가요?
안녕하세요, 돈까스는맛있어 님!private 메서드를 테스트 하지 않는다고 한 적은 없습니다.private 메서드는 해당 메서드를 사용하고 있는 public 메서드를 통해서 테스트 케이스가 정의되고, 테스팅되어야 한다고 이야기한 것인데요.또한 private 메서드를 public 메서드로 바꾸는 것은 행위는 간단하나, 객체의 설계 관점에서 보았을 때 좋은 구조가 아닙니다.private 메서드는 외부에서 그 로직을 알지 못하도록 캡슐화 되어있는 것인데, 이를 외부에 공개함으로써 예기치 못한 정보의 노출과, 사이드이펙트(잘못 사용하거나 하는 등)를 야기할 수 있습니다.도움이 되셨기를 바랍니다.감사합니다. 🙂
- 0
- 2
- 42
질문&답변
2024.11.02
서비스단 private 메서드의 책임을 새로운 객체로 분리 시, repository 의존성 이슈에 대해
안녕하세요, joon1754 님!제가 질문을 이해한 내용은 다음과 같습니다.Repository에서 private 메서드가 생겼을 때, 이를 다른 객체로 분리하는 것에 대한 이야기 맞을까요?일단 private 메서드를 객체로 분리하는 것 이전에 고려되어야 할 것은, 해당 private 메서드를 사용하는 public 메서드를 통해 충분히 테스팅을 시도하는 것입니다.만약 그렇게 하더라도 충분치 않고 뭔가 과도한 책임을 가지고 있는 것 같다면, 그 때 객체 분리를 고려하는 것이죠.Repository에서 객체(이하 객체 A)를 분리한다고 했을 때, 사실 Service가 그 새로운 객체 A를 알도록 하는 것이 아니라, Repository만 해당 객체를 알고 있도록 구성하면 되지 않을까 싶어요.즉, Service가 Repository와 A 모두를 의존하는 것이 아니라, Service - Repository - A 와 같은 형태면 될 것 같아요.도움이 되셨기를 바랍니다.감사합니다 🙂
- 0
- 2
- 61
질문&답변
2024.11.02
안녕하세요 @Autowired, @Mockbean, @Mock, @InjectMocks에 대해 질문 있습니다.
안녕하세요, 감바스 님! 1. 각 어노테이션을 언제 주로 사용하는지에 대해 아래와 같이 정리를 했는데 맞게 정리 한 건지 궁금합니다.네 잘 정리해 주셨네요 ㅎㅎ 2. 위 질문 중에 "@Mockbean과 @Autowired를 섞어 사용하는 경우" 코드에 대해 질문이 있습니다. 컨트롤러에 대한 단위 테스트를 하기 위해 @MockBean을 사용하여 서비스에 대한 의존성을 끊는 부분은 이해를 했습니다. 근데 결국 서비스 객체를 가져다 쓰니 서비스가 의존하고 있는 Repository에 대한 부분도 @MockBean을 사용하여 스프링 컨테이너에 Mock을 등록해야 하지 않나 라는 생각이 듭니다.서비스를 mocking 했으니 애초에 Controller는 Repository에 접근할 수가 없습니다.따라서 굳이 Repository까지 MockBean으로 등록하지 않아도 되는거죠.실제로 서비스를 호출하는 부분과 Repository를 호출하는 부분에 디버거를 걸고 테스트를 실행시켜 보세요 :) 3. 아래 코드에 대해 질문이 있습니다. 실제 스프링 부트를 실행 하면 각 서비스 객체와 Repository 객체 모두 스프링 컨테이너에 등록되어 서비스 레이어쪽에서 Repository레이어에 의존하는 상황입니다. 저는 스프링 컨테이너에 빈들도 잘 등록되고 서로 잘 데이터를 주고 받는지도 테스트를 해야한다고 생각하는데 아래와 같이 @InjectMocks과 @Mock을 사용하면 스프링 컨테이너와 상관이 없어져서 아래와 같은 상황에서 @InjectMocks과 @Mock을 사용하여 테스트 코드를 작성해도 되는지 궁금합니다.그래서 제시해주신 코드는 스프링과 무관한 단위 테스트를 작성할 때 사용하게 되고요.스프링 통합 테스트를 진행할 때에는 MockBean을 사용하게 됩니다. 4. 1번 질문과 같이 정리를 했지만 @Autowired와 @Mockbean 사용에 대해 헷갈리는점이 있어 아래 내용을 정리 했는데 맞게 이해를 한건지 궁금합니다.@Autowired를 테스트 코드에서 사용하는 핵심은 해당 기능을 스프링 컨테이너에 등록하는걸 넘어서 해당 객체의 기능을 실제 사용하겠다 라는 의미다.@Mockbean을 테스트 코드에서 사용하는 핵심 이유는 의존 관계를 끊기 위함이다. 예를 들어 컨트롤러 쪽에서 서비스쪽에 강한 의존관계를 가지고 있어 우선 @Mockbean을 통해 생성한 가짜 객체를 스프링 컨테이너에 등록하고 이 가짜 객체를 컨트롤러쪽에서 의존하고 있는 객체에 넣어줘서 의존관계를 끊는다. 주의할점은 @Mockbean을 통해 생성한 가짜 객체의 기능은 사용하지 않는다. 가짜 객체의 기능을 사용하지 않는다기 보다는, 테스트 시 프로덕션 코드에서 가짜 객체를 호출까지는 하나, 임의로 지정한 반환값을 돌려줍니다. 5. 아래 코드에서 @MockBean을 통해 생성한 ProductService 객체는 가짜 객체이므로 ProductRepository 객체를 못 불러오나요?Mock 객체는 기본적으로 실제 객체를 모방한 껍데기 입니다.우리가 mocking을 통해서 행위를 마음대로 지정할 수 있는 것도 그 때문이죠.따라서 Mock 객체는 ProductRepository를 가지고 있지 않습니다. ProductService의 모습을 흉내만 내고 있는 것이죠. 위에서 말씀드린 것처럼, 실제 디버거를 켜고 mock 객체가 어떻게 생겼는지 살펴보시길 바라요.도움이 되셨기를 바랍니다.감사합니다 🙂
- 0
- 1
- 87