③Junit Service 테스트 -1 Service book등록
일본에서 일하는 외노자 로써 내용이 일본어가 포함될 수 있습니다.!!
하기에 동영상 참조 하였습니다. (문제가 될 시 삭제하겠습니다.)
https://www.youtube.com/watch?v=kYqGAM2culU&list=PL93mKxaRDidEZfpXoyWZ-2ZLsYrQByDMP
이제부터 Service를 Junit 테스트를 진행 해보도록 하겠습니다.
최하단에는 서비스 본문이 있습니다.
메서드, 애노테이션 하나하나 알아 가 보도록 하겠습니다.
1. 서비스 클래스와 book 등록
@RequiredArgsConstructor
@Service
public class BookService {
private final BookRepository bookRepository;
private final MailSender mailSender;
//1. book 登録
@Transactional(rollbackFor = RuntimeException.class)
public BookRespDto bookSave(BookSaveReqDto dto) {
Book bookPS = bookRepository.save(dto.toEntity());
if (bookPS != null) {
if (!mailSender.send()) {
throw new RuntimeException("メールの転送が失敗しました。");
}
}
return bookPS.toDto();
}
BookService - bookSave
@RequiredArgsConstructor
@RequiredArgsConstructor을 클래스에 부여하는 것으로 필수의 멤버 (final 의 멤버)에 값을 세트 하기 위한 인수 첨부 constructor 을 자동 생성할 수가 있다. Lombok을 추가하는 것으로 사용할 수 있다.
@Transactional
메소드가 호출 된 타이밍 (정확하게는 메소드 시작 전)에 트랜잭션이 시작되고 대상 메소드가 성공적으로 종료되면 커밋되고 예외로 종료되면 롤백됩니다.
rollbackFor은 스프링에서 RuntimeException이 발생하면 rollback을 한다는 것이다.
@Transactional에 아무설정도 하지 않으면 runtimeException과 error둘다 설정 하게 된다.
코드 해석해보자면, bookRepository.save(dto.toentity)의 리턴을 bookPS에 저장한다.
bookPS는 DB에 저장된 값을 가지고 있는다.
BookSaveReqDto의 toEntity()메서드는 값을 Book객체로 반환한다.
리턴 값으로 BookPS.toDto(); 로 되어있지만 toDto로 인해 BookRespDto객체로 저장된다.
BookRespDto를 사용한다. Book클래스 안에는 BookRespDto인 toDto가 정의 되어 있다.
BookRespDto BookSaveDto 대해서 알아보도록 하자..
1-1 BookRespDto (responseDto)
@NoArgsConstructor
@Getter
public class BookRespDto {
private Long id;
private String title;
private String author;
@Builder
public BookRespDto(Long id, String title, String author) {
super();
this.id = id;
this.title = title;
this.author = author;
}
}
@NoArgsConstructor
@NoArgsConstructor을 클래스에 부여하여 기본 생성자를 자동으로 생성할 수 있습니다.
Getter가 있는 것으로 응답의 response로 사용되고 있다.
1-2 BookSaveReqDto ()
@Getter
@Setter // Controller から Setterが呼ばれてDtoに入れる
public class BookSaveReqDto {
private String title;
private String author;
public Book toEntity() {
return Book.builder()
.title(title)
.author(author)
.build();
}
}
Controller로부터 setter가 불려지는 Dto이다.
toEntity로써 book 객체를 save하는데에 사용된다.
BookSaveReqDto와 BookRespDto가 다른 점이 하나 있는데
private id가 있다. 이것은 save로 들어온 것은 영속화 되지 않은(DB에 저장되지 않은) 것에는 id가 없고
DB에 저장된 데이터인 BookResp이기에 다르다.
Book클래스의 toDto메서드
public BookRespDto toDto() {
return BookRespDto.builder()
.id(id)
.title(title)
.author(author)
.build();
}
toDto는 Book 객체인 bookPS를 BookRespDto의 toDto()의 메서드로 불러서 Book객체가 아닌 BookRespDto객체로 반환 한다.
package com.junitP.junit.service;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.junitP.junit.domain.Book;
import com.junitP.junit.domain.BookRepository;
import com.junitP.junit.util.MailSender;
import com.junitP.junit.web.dto.BookRespDto;
import com.junitP.junit.web.dto.BookSaveReqDto;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Service
public class BookService {
private final BookRepository bookRepository;
private final MailSender mailSender;
//1. book 登録
@Transactional(rollbackFor = RuntimeException.class)
public BookRespDto bookSave(BookSaveReqDto dto) {
Book bookPS = bookRepository.save(dto.toEntity());
if (bookPS != null) {
if (!mailSender.send()) {
throw new RuntimeException("メールの転送が失敗しました。");
}
}
return bookPS.toDto();
}
//2. book list
public List<BookRespDto> bookList() {
List<BookRespDto> dtos = bookRepository.findAll().stream()
//.map((bookPS) -> bookPS.toDto())
.map(Book::toDto)
.collect(Collectors.toList());
//print
dtos.stream().forEach((dto)-> {
System.out.println(dto.getId());
System.out.println(dto.getTitle());
System.out.println(dto.getAuthor());
System.out.println("1.-------------------------------------------------------------------------");
});
return dtos;
}
//3. book 詳細 search
public BookRespDto booksSearch(Long id) {
Optional<Book> bookOP = bookRepository.findById(id);
if(bookOP.isPresent()) {
Book bookPS = bookOP.get();
return bookPS.toDto();
} else {
throw new RuntimeException("IDが見つかりません");
}
}
//4. book delete
@Transactional(rollbackFor = RuntimeException.class)
public void bookDelete(Long id) {
bookRepository.deleteById(id);
}
//5. book 修正
@Transactional(rollbackFor = RuntimeException.class)
public BookRespDto bookCollection(Long id, BookSaveReqDto dto) {
Optional<Book> bookOP = bookRepository.findById(id);
if(bookOP.isPresent()) {
Book bookPS = bookOP.get();
bookPS.update(dto.getTitle(), dto.getAuthor());
return bookPS.toDto();
} else {
throw new RuntimeException("IDが見つかりません");
}
}
}
이번 게시물은 book등록까지 알아봤습니다. ...
다음에는 book리스트 수정 검색 삭제 알아보도록 하겠습니다.