public void messageSendSave(String messageSendTitle, String receiveMemberId, String messageSendContent, String loginMember, Optional<Member> SendMemberInfo) {
MessageSend messageSend = new MessageSend(messageSendTitle, messageSendContent, String.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))), loginMember, receiveMemberId);
messageSend.addMessageSendMember(SendMemberInfo.get());
messageSendRepository.save(messageSend);//Spring JPA save기능 사용
}
↑
해당 메서드를 테스트하기 위해
@Test
void messageSendSave(){
Member member = new Member("sendId", "123", "남자", "whdlsxo123@naver.com", LocalDate.now(), "010-2323-4343");
Optional<Member> sendMemberInfo = Optional.of(member);
serviceMethod.messageSendSave("messageSendTitle", "receiveId","content","loginId",sendMemberInfo);
Optional<MessageSend> findMessageSend = messageSendRepository.findById(1L);
assertThat(findMessageSend.get().getMessageSendTitle()).isEqualTo("messageSendTitle");
}
이와 같이 코드를 구성했다. 하지만
이와 같은 에러가 발생했다.
오류 메시지를 읽어보면 이유는 간단하다.
@Entity
@Getter @Setter @ToString
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
public class Member {
@Id
@Column(name = "MEMBER_ID")
private String memberId;
private String memberPassword;
private String memberSex;
private String memberEmail;
private LocalDate memberDate;
private String memberPnumber;
@OneToMany(mappedBy = "member",cascade = CascadeType.REMOVE,orphanRemoval = true )
List<Bbs> bbs = new ArrayList<>();
@OneToMany(mappedBy = "member",cascade = CascadeType.REMOVE,orphanRemoval = true)
List<Comment> comments = new ArrayList<>();
@OneToMany(mappedBy = "member",cascade = CascadeType.REMOVE,orphanRemoval = true)
List<MessageReceive> messageReceive = new ArrayList<>();
@OneToMany(mappedBy = "member",cascade = CascadeType.REMOVE,orphanRemoval = true)
List<MessageSend> messageSend = new ArrayList<>();
↑
Member entity
@Entity
@Setter
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
public class MessageSend {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "MESSAGE_SEND_NO")
private Long messageSendNo; //기본키
private String messageSendTitle;
private String messageSendContent;
private String messageSendDate;
private String sendMemberId;
private String receiveMemberId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MEMBER_ID")
private Member member;
↑
MessageSend entity
@OneToMany(mappedBy = "member",cascade = CascadeType.REMOVE,orphanRemoval = true)
List<MessageSend> messageSend = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MEMBER_ID")
private Member member;
연관관계 주인이 messageSend로 정해져 있는
member와 messageSend는 1:N 관계이다.
하지만
@Test
void messageSendSave(){
Member member = new Member("sendId", "123", "남자", "whdlsxo123@naver.com", LocalDate.now(), "010-2323-4343");
Optional<Member> sendMemberInfo = Optional.of(member);
serviceMethod.messageSendSave("messageSendTitle", "receiveId","content","loginId",sendMemberInfo);
Optional<MessageSend> findMessageSend = messageSendRepository.findById(1L);
assertThat(findMessageSend.get().getMessageSendTitle()).isEqualTo("messageSendTitle");
}
이 코드에서 영속성 콘텍스트에 member객체가 없는데 messageSendSave를 저장하려고 하니 너무 당연하게
에러가 나는 것이다. 따라서
@Test
void messageSendSave(){
Member member = new Member("sendId", "123", "남자", "whdlsxo123@naver.com", LocalDate.now(), "010-2323-4343");
Optional<Member> sendMemberInfo = Optional.of(member);
memberRepository.saveMember(member); //앞에 추가
serviceMethod.messageSendSave("messageSendTitle", "receiveId","content","loginId",sendMemberInfo);
Optional<MessageSend> findMessageSend = messageSendRepository.findById(1L);
assertThat(findMessageSend.get().getMessageSendTitle()).isEqualTo("messageSendTitle");
}
이와 같이 member객체를 영속성 콘텍스트에 저장하고 진행하면
성공적으로 테스트가 완료된다.
테스트 코드를 짜면서
public void messageSendSave(String messageSendTitle, String receiveMemberId, String messageSendContent, String loginMember, Optional<Member> SendMemberInfo) {
MessageSend messageSend = new MessageSend(messageSendTitle, messageSendContent, String.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))), loginMember, receiveMemberId);
messageSend.addMessageSendMember(SendMemberInfo.get());
messageSendRepository.save(messageSend);//Spring JPA save기능 사용
}
↑
이와 같이 messageSendTitle이 파라미터가 있어야 하는 자리에
public void messageSendSave(String receiveMemberId, String receiveMemberId, String messageSendContent, String loginMember, Optional<Member> SendMemberInfo) {
MessageSend messageSend = new MessageSend(receiveMemberId, messageSendContent, String.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))), loginMember, receiveMemberId);
messageSend.addMessageSendMember(SendMemberInfo.get());
messageSendRepository.save(messageSend);//Spring JPA save기능 사용
}
↑
receiveMemberId 파라미터가 전달되는 오류도 발견했다.
이 오류 경험으로
TDD를 해야하는 이유 4가지 중
1. 개발자가 의도한 대로 로직이 동작하는지 명확하게 알 수 있고, 로직에 대해 보증할 수 있다.
2. 사전에 다양한 케이스를 고려해봄으로써 문제가 될 수 있는 잠재적 오류들을 방어할 수 있다.
3. 아키텍처와 로직이 깔끔해진다.
4. 이후에 다른 사람이 로직을 수정하게 될 때, 로직의 변경에 대한 영향도가 명확하게 보인다.
1번에 해당되는 내용을 직접 경험한 거 같다.
추가적으로
백기선 님 유튜브 라이브를 보는데 켄트 백의 TTD(테스트 주도 개발)이라는 책을 꼭 보라고 조언해주셨고
TDD에 대해 깊은 이해를 하기 위해 책을 읽어야겠다.
'개발일기 > 프로젝트 일기' 카테고리의 다른 글
HealthDuo - 쪽지 보내기 기능 (0) | 2022.07.15 |
---|---|
HealthDuo-java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (0) | 2022.07.11 |
HealthDuo-Thymeleaf 에서의 Context Path 사용방법 (0) | 2022.07.11 |
HomeTheater - 결제 페이지 (0) | 2022.07.10 |
HealthDuo-게시글 쓰기 (0) | 2022.06.28 |