Part 9. 비즈니스 계층

9.2 비즈니스 계층의 구현과 테스트

  • BoardMapper와 BoardService, BoardServiceImpl에 대한 구조 설정이 완료되었으므로 'src/test/java' 밑에 org.zerock.service.BoardServiceTests 클래스를 작성해 테스트 작업을 진행한다.
< BoardServiceTests 클래스 >
package org.zerock.service;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
// Java Config
// @ContextConfiguration(classes = {org.zerock.config.RootConfig.class})
@Log4j
public class BoardServiceTests {
	@Setter(onMethod_ = {@Autowired })
	private BoardService service;	
	@Test
	public void testExist() {
		log.info(service);
		assertNotNull(service);
	}
}
  • BoardServiceTests의 첫 테스트는 BoardService 객체가 제대로 주입이 가능한지 확인하는 작업으로 시작한다.
  • 정상적으로 BoardService 객체가 생성되고 BoardMapper가 주입되었다면 아래와 같이 BoardService 객체와 데이터베이스 관련 로그가 같이 출력된다.
INFO : org.zerock.service.BoardServiceTests - org.zerock.service.BoardServiceImpl@64693226
INFO : org.springframework.context.support.GenericApplicationContext - Closing org.springframework.context.support.GenericApplicationContext@65b3f4a4: startup date [Wed Aug 09 22:21:26 KST 2023]; root of context hierarchy
INFO : com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
INFO : jdbc.connection - 1. Connection closed
INFO : jdbc.audit - 1. Connection.close() returned 
INFO : jdbc.connection - 2. Connection closed
INFO : jdbc.audit - 2. Connection.close() returned 
INFO : jdbc.connection - 3. Connection closed
INFO : jdbc.audit - 3. Connection.close() returned 
INFO : jdbc.connection - 4. Connection closed
INFO : jdbc.audit - 4. Connection.close() returned 
INFO : jdbc.connection - 10. Connection opened
INFO : jdbc.audit - 10. Connection.new Connection returned 
INFO : jdbc.connection - 5. Connection closed
INFO : jdbc.audit - 5. Connection.close() returned 
INFO : jdbc.audit - 10. Connection.setReadOnly(false) returned 
INFO : jdbc.audit - 10. Connection.setAutoCommit(true) returned 
INFO : jdbc.connection - 6. Connection closed
INFO : jdbc.audit - 6. Connection.close() returned 
INFO : jdbc.connection - 7. Connection closed
INFO : jdbc.audit - 7. Connection.close() returned 
INFO : jdbc.connection - 8. Connection closed
INFO : jdbc.audit - 8. Connection.close() returned 
INFO : jdbc.connection - 9. Connection closed
INFO : jdbc.audit - 9. Connection.close() returned 
INFO : jdbc.connection - 10. Connection closed
INFO : jdbc.audit - 10. Connection.close() returned 
INFO : com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.

9.2.1 등록 작업의 구현과 테스트

  • 등록 작업은 BoardServiceImpl에서 파라미터로 전달되는 BoardVO 타입의 객체를 BoardMapper를 통해 처리한다.
  • 구현되는 코드는 아래와 같다.
< BoardServiceImpl 클래스 >
	@Override
	public void register(BoardVO board) {		
		log.info("register......" + board);		
		mapper.insertSelectKey(board);
	}
  • BoardService는 void 타입으로 설계되었으므로 mapper.insertSelectKey()의 반환 값인 int를 사용하지 않고 있지만, 필요하다면 예외 처리나 void 대신에 int 타입을 이용해 사용할 수 있다.
  • mapper의 insertSelectKey()를 이요해 나중에 생성된 게시물의 번호를 확인할 수 있게 작성하고, 이에 대한 테스트 코드는 아래와 같이 작성한다.
< BoardServiceTests 클래스 >
	@Test
	public void testRegister() {		
		BoardVO board = new BoardVO();
		board.setTitle("새로 작성하는 글");
		board.setContent("새로 작성하는 내용");
		board.setWriter("newbie");		
		service.register(board);		
		log.info("생성된 게시물의 번호: " + board.getBno());	
	}
  • testRegister()의 테스트 결과는 다음과 같이 생성된 게시물의 번호를 확인할 수 있다.
INFO : jdbc.sqltiming - insert into tbl_board (bno,title,content, writer) values (41, '새로 작성하는 글', '새로 작성하는 내용', 'newbie') 
 {executed in 70 msec}
INFO : jdbc.audit - 1. PreparedStatement.execute() returned false
INFO : jdbc.audit - 1. PreparedStatement.getUpdateCount() returned 1
INFO : jdbc.audit - 1. PreparedStatement.isClosed() returned false
INFO : jdbc.audit - 1. PreparedStatement.close() returned 
INFO : jdbc.audit - 1. Connection.clearWarnings() returned 
INFO : org.zerock.service.BoardServiceTests - 생성된 게시물의 번호: 41

9.2.2 목록(리스트) 작업의 구현과 테스트

  • BoardServiceImpl 클래스에서 현재 테이블에 저장된 모든 데이터를 가져오는 getList()는 아래와 같이 구현된다.
< BoardServiceImpl 클래스 >
	@Override
	public List<BoardVO> getList() {	
		log.info("getList.......");		
		return mapper.getList();
	}
  • 테스트 코드는 아래와 같이 작성할 수 있다.
< org.zerock.service.BoardServiceTest 클래스 >
	// 테이블에 저장된 모든 데이터를 가져오기
	@Test
	public void testGetList() {		
		service.getList().forEach(board -> log.info(board));
	}
  • 테스트의 실행 결과로 등록 작업을 테스트 할 때 추가된 데이터가 정상적으로 나오는지 확인한다.
INFO : jdbc.resultsettable - 
|----|---------------------|----------------------|-------|----------------------|----------------------|
|bno |title                |content               |writer |regdate               |updatedate            |
|----|---------------------|----------------------|-------|----------------------|----------------------|
|1   |테스트 제목               |테스트 내용                |USER00 |2023-08-09 11:33:55.0 |2023-08-09 11:33:55.0 |
|2   |테스트 제목               |테스트 내용                |USER00 |2023-08-09 11:33:56.0 |2023-08-09 11:33:56.0 |
|4   |테스트 제목               |테스트 내용                |USER00 |2023-08-09 11:33:57.0 |2023-08-09 11:33:57.0 |
|5   |수정된 제목               |수정된 제목                |user00 |2023-08-09 11:34:00.0 |2023-08-09 20:31:20.0 |
|21  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 19:31:42.0 |2023-08-09 19:31:42.0 |
|22  |새로 작성하는 글 select key |새로 작성하는 내용 select key |newbie |2023-08-09 19:36:11.0 |2023-08-09 19:36:11.0 |
|23  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 19:36:11.0 |2023-08-09 19:36:11.0 |
|24  |새로 작성하는 글 select key |새로 작성하는 내용 select key |newbie |2023-08-09 20:11:11.0 |2023-08-09 20:11:11.0 |
|25  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 20:11:11.0 |2023-08-09 20:11:11.0 |
|26  |새로 작성하는 글 select key |새로 작성하는 내용 select key |newbie |2023-08-09 20:20:00.0 |2023-08-09 20:20:00.0 |
|27  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 20:20:00.0 |2023-08-09 20:20:00.0 |
|28  |새로 작성하는 글 select key |새로 작성하는 내용 select key |newbie |2023-08-09 20:31:20.0 |2023-08-09 20:31:20.0 |
|29  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 20:31:20.0 |2023-08-09 20:31:20.0 |
|41  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 22:55:55.0 |2023-08-09 22:55:55.0 |
|----|---------------------|----------------------|-------|----------------------|----------------------|

9.2.3 조회 작업의 구현과 테스트

  • 조회는 게시물의 번호가 파라미터이고 BoardVO의 인스턴스가 리턴이 된다.
< BoardServiceImpl 클래스 >
	// 게시물 조회
	@Override
	public BoardVO get(Long bno) {
		log.info("get......" + bno);
		return mapper.read(bno);		
	}
  • 테스트 코드는 다음과 같이 작성한다.
< org.zerock.service.BoardServiceTests 클래스 >
	// 게시물 조회
	@Test
	public void testGet() {
		log.info(service.get(1L));
	}
  • 테스트 결과는 다음과 같다.
INFO : jdbc.resultsettable - 
|----|---------------------|----------------------|-------|----------------------|----------------------|
|bno |title                |content               |writer |regdate               |updatedate            |
|----|---------------------|----------------------|-------|----------------------|----------------------|
|1   |테스트 제목               |테스트 내용                |USER00 |2023-08-09 11:33:55.0 |2023-08-09 11:33:55.0 |
|2   |테스트 제목               |테스트 내용                |USER00 |2023-08-09 11:33:56.0 |2023-08-09 11:33:56.0 |
|4   |테스트 제목               |테스트 내용                |USER00 |2023-08-09 11:33:57.0 |2023-08-09 11:33:57.0 |
|5   |수정된 제목               |수정된 제목                |user00 |2023-08-09 11:34:00.0 |2023-08-09 20:31:20.0 |
|21  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 19:31:42.0 |2023-08-09 19:31:42.0 |
|22  |새로 작성하는 글 select key |새로 작성하는 내용 select key |newbie |2023-08-09 19:36:11.0 |2023-08-09 19:36:11.0 |
|23  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 19:36:11.0 |2023-08-09 19:36:11.0 |
|24  |새로 작성하는 글 select key |새로 작성하는 내용 select key |newbie |2023-08-09 20:11:11.0 |2023-08-09 20:11:11.0 |
|25  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 20:11:11.0 |2023-08-09 20:11:11.0 |
|26  |새로 작성하는 글 select key |새로 작성하는 내용 select key |newbie |2023-08-09 20:20:00.0 |2023-08-09 20:20:00.0 |
|27  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 20:20:00.0 |2023-08-09 20:20:00.0 |
|28  |새로 작성하는 글 select key |새로 작성하는 내용 select key |newbie |2023-08-09 20:31:20.0 |2023-08-09 20:31:20.0 |
|29  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 20:31:20.0 |2023-08-09 20:31:20.0 |
|41  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 22:55:55.0 |2023-08-09 22:55:55.0 |
|42  |새로 작성하는 글            |새로 작성하는 내용            |newbie |2023-08-09 23:03:06.0 |2023-08-09 23:03:06.0 |
|----|---------------------|----------------------|-------|----------------------|----------------------|

9.2.4 삭제/수정 구현과 테스트

  • 삭제/수정은 메서드의 리턴 타입을 void로 설계할 수 있지만 엄격하게 처리하기 위해 Boolean 타입으로 처리한다.
< org.zerock.service.BoardServiceImpl 클래스 >
	// 게시물 수정
	@Override
	public boolean modify(BoardVO board) {
		log.info("modify......." + board);		
		return mapper.update(board) == 1;
	}
	// 게시물 삭제
	@Override
	public boolean remove(Long bno) {		
		log.info("remove......" + bno);		
		return mapper.delete(bno) == 1;
	}
  • 정상적으로 수정과 삭제가 이루어지면 1이라는 값이 반환되기 때문에 '==' 연산자를 이용해서 true/false를 처리할 수 있다.
  • 테스트 코드는 다음과 같이 작성한다.
< org.zerock.service.BoardServiceTests 클래스 >
	// 게시물 삭제
	@Test
	public void testDelete() {		
		// 게시물 번호의 존재 여부를 확인하고 테스트 할 것
		log.info("REMOVE RESULT: " + service.remove(2L));
	}	
	// 게시물 수정
	@Test
	public void testUpdate() {		
		BoardVO board = service.get(1L);		
		if (board == null) {
			return;
		}			
		board.setTitle("제목 수정합니다.");
		log.info("MODIFY RESULT: " + service.modify(board));
	}
  • testDelete()의 경우에는 해당 게시물이 존재할 때 true를 반환하는 것을 확인할 수 있고, testUpdate()의 경우에는 특정한 게시물을 먼저 조회하고, title 값을 수정한 후 이를 업데이트한다.
profile
한 걸음 한 걸음 나아가는 개발자

0개의 댓글