- 사용자 레벨 관리 기능 추가
지금까지 만든 UserDao는 CRUD라고 불리는 가장 기초적인 작업만 가능하다.
이제 여기에 간단한 비즈니즈 로직을 추가해보자. 지금까지 만들었던 UserDao를 다수의 회원이 가입할 수 있는 인터넷 서비스의 사용자 관리 모듈에 적용해보자.
필드 추가
먼저 UserVO 클래스에 사용자의 레벨을 저장할 필드를 추가하자. private static final int BASIC = 1;처럼 숫자 타입을 직접 사용하는 것보다는 자바 5 이상에서 제공하는 이늄enum을 이용하는 게 안전하고 편리하다. 이늄은 아래와 같이 정의한다.
이렇게 만들어진 Level 이늄은 내부에는 DB에 저장할 int 타입의 값을 갖고 있지만, 겉으로는 Level 타입의 오브젝트이기 때문에 안전하게 사용할 수 있다.
User 필드 추가
각각 접근자와 수정자 메소드를 추가해주고 DB의 User테이블에 필드를 추가해주자.
UserDaoTest 테스트 수정
UserVO의 생성자 함수를 위와 같이 수정해주고 UserDaoTest의 @Before 메소드를 아래와 같이 수정해준다.
다음은 UserDaoTest 테스트에서 두 개의 UserVO 오브젝트 필드 값이 모두 같은지 비교하는 checkSameUser() 메소드를 수정한다.
이전에는 addAndGet()메소드에서는 checkSameUser() 메소드를 사용하지 않았지만 앞으로 추가되거나 변경돼도 UserVO 오브젝트를 비교하는 로직을 일정하게 유지할 수 있도록 checkSameUser() 메소드를 사용하도록 하자.
UserDaoJdbc 수정
성공적인 테스트 수행을 위해 UserDaoJdbc 클래스를 수정하도록 하자.
여기서 주의할 것은 Level 타입의 level 필드를 사용하는 부분이다. Level 이늄은 오브젝트이므로 DB에 저장될 수 있는 SQL 타입이 아니다. 따라서 DB에 저장 가능한 정수형 값으로 변환해줘야 한다. 각 Level 이늄의 DB 저장용 값을 얻기 위해서는 Level에 미리 만들어둔 intValue() 메서드를 사용한다. add() 메서드에서 이 메서드를 사용했다.
-사용자 수정 기능 추가
수정 기능 테스트 추가
UserDao와 UserDaoJdbc 수정
dao 변수의 타입인 UserDao 인터페이스에 update() 메소드가 없기 때문에 컴파일 에러가 날 것이다. 그러므로 UserDao 인터페이스에 update() 메소드를 추가해주자. 그리고 UserDaoJdbc에서 update() 메소드를 구현해주면 된다.
수정 테스트 보완
가장 많은 실수가 일어나는 곳은 바로 SQL 문장이다. 필드 이름이나 SQL 키워드를 잘못 넣은 거라면 테스트를 돌려보면 에러가 나니 쉽게 확인할 수 있다. 하지만 UPDATE 문장에서는 WHERE 절을 빼먹어도 정상적으로 동작하는 거처럼 보인다. 이 문제를 해결할 방법을 생각해보자.
첫 번째 방법은 update()가 반환하는 리턴 값을 확인하는 것이다. 비록 리턴 값을 받았더라도 수정을 원하는 데이터의 개수와 반환받은 값이 다르면 문제가 있다는 것을 알 수 있다.
두 번째 방법은 원하는 사용자 외의 정보는 변경되지 않았음을 직접 확인하는 것이다. 사용자를 두 명 등록해놓고 그중 하나만 수정한 뒤에 수정된 사용자와 수정하지 않은 사용자의 정보를 모두 확인하면 된다.
우리는 두 번째 방법을 사용해서 테스트를 보완해보자.
update() 메소드의 SQL에서 WHERE 절을 빼먹었다면 이 테스트는 실패로 끝날 것이다. 이제 본격적인 사용자 관리 비즈니스 로직을 구현해보자.
- UserService.upgradeLevels()
사용자 관리 로직을 UserDaoJdbc에 놓는 것은 적당하지 않다. DAO는 데이터를 어떻게 가져오고 조작할지 다루는 곳이지 비즈니스 로직을 두는 곳이 아니다. 그러므로 사용자 관리 비즈니스 로직을 담을 클래스를 하나 추가하자.
비즈니스 로직 서비스를 제공한다는 의미에서 클래스 이름을 UserService로 한다.
UserService는 UserDao인터페이스 타입으로 userDao 빈을 DI 받아 사용하게 만든다.
UserService는 UserDao의 구현 클래스가 바뀌어도 영향받지 않도록 해야 한다.
UserService의 클래스 레벨 의존관계를 정리해보면 아래와 같다.
UserService 클래스와 빈 등록
UserDao 오브젝트의 DI가 가능하도록 수정자 메소드도 추가한다.
스프링 설정 파일에 userService 아이디로 빈을 추가한다. userDao 빈을 DI 받도록 프로퍼티를 추가해준다.
UserServiceTest 테스트 클래스
UserServiceTest 클래스를 추가하고 테스트 대상인 UserService 빈을 제공받을 수 있도록 @Autowired가 붙은 인스턴스 변수로 선언해준다.
upgradeLevels() 메소드
먼저 모든 사용자 정보를 DAO에서 가져온 후에 한 명씩 레벨 변경 작업을 수행한다. 현재 사용자의 레벨이 변경됐는지를 확인할 수 있도록 플래그를 하나 선언한다. changed 플래그를 확인해서 레벨 변경이 있는 경우에만 UserDao의 update()를 이용해 수정 내용을 DB에 반영한다.
upgradeLevels() 테스트
사용자 레벨은 3가지가 있고 변경이 일어나지 않는 GOLD는 제외한 나머지 두 가지는 업그레이드가 되는 경우와 아닌 경우가 있을 수 있으므로 최소한 다섯 가지 경우를 살펴봐야 한다.
테스트를 사용할 데이터를 경계가 되는 값의 전후로 선택하는 것이 좋다.
업그레이드 작업이 끝나면 사용자 정보를 하나씩 가져와 레벨의 변경 여부를 확인하면 된다.
UserService.add();
처음 가입한 사람의 레벨은 BASIC으로 설정되어야 한다. 이 로직을 UserService에 add()를 만들어두고 사용자가 등록될 때 적용할 만한 비즈니스 로직을 담당하게 하자.
테스트 케이스는 레벨이 미리 정해진 경우와 레벨이 비어있는 경우 두 경우를 만들면 된다.
'Spring > 토비의 스프링 정리' 카테고리의 다른 글
3.5 템플릿과 콜백 (0) | 2022.04.09 |
---|---|
3.3 JDBC 전략 패턴의 최적화, 3.4 컨텍스트와 DI (0) | 2022.04.08 |
3.1 다시 보는 초난감 DAO (0) | 2022.04.07 |
2.5 학습 테스트로 배우는 스프링 (0) | 2022.04.06 |
2.4 스프링 테스트 적용 (0) | 2022.04.05 |