이렇게 구성하도록 보면서 하고있다. 물론 아직 application 계층을 벗어나지 못하고 있다.
아주 간단한 User모델부터 시작해서 API Controller까지 다 붙이면 하나씩 늘리기로 생각했다.
처음부터 모두 가능한 걸로 해야지 하다보면 전부를 어떻게 해야 할지 몰라서 못하더라 나는 그랬다.
public class User {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
public User(String name) {
this.name = name;
}
public void update(User user) {
this.name = user.getName();
}
}
setter는 언제 어디서 호출되서 객체를 수정 될지 모르니까 사용하지 말라는 인터넷 강의의 말을 듣고
Username를 바굴때는 다른 User객체에서 getName를 통해 업데이트 하도록 만들었다. 추후에 필드가 추가 되면 어떤 필드만 변경 되었는지 어떻게 알고 처리 할진 모르겠지만 우선 JPA 변동 감지를 통해 처리하였다.
interface로 서비스로직을 정의하고 Impl를 통해 구현한다. 외부에 entity를 직접 노출하지 않기 위해 Dto를 만들어서 entity계층과 통신 할때 변경하여 보내도록 한다.
class UserRepositoryTest {
@Autowired
UserRepository userRepository;
@Test
public void userCreation() throws Exception {
//given
User user = new User("nakim");
userRepository.save(user);
//when
User findUser = userRepository.findById(user.getId()).orElseThrow();
//then
assertThat(findUser.getId()).isEqualTo(user.getId());
assertThat(findUser.getName()).isEqualTo(user.getName());
}
@Test
public void basicCRUD() throws Exception {
User user1 = new User("nakim1");
User user2 = new User("nakim2");
userRepository.save(user1);
userRepository.save(user2);
//리스트 검증
List<User> all = userRepository.findAll();
assertThat(all.size()).isEqualTo(2);
//카운트 검증
long total = userRepository.count();
assertThat(total).isEqualTo(2);
//삭제 검증
userRepository.delete(user1);
userRepository.delete(user2);
long deleteCount = userRepository.count();
assertThat(deleteCount).isEqualTo(0);
}
}
userrepository 계층에서 테스트 할땐 잘 만들어졌는지 삭제는 잘 되는지 junit를 통해 검증했다.
물론 spirng에 의존적으로 테스트를 하게 되었는지 순수하게 자바코드만으로도 테스트 하는걸 나중에 해봐야 겠다고 생각했다. 일단 스프링으로 돌리려면 조금 느리다.
아래의 테스트를 만들 때 삽질을 많이 했지만 결국 실패해서 spring에 의존적으로 만들었다.
class UserCommandServiceTest {
@Autowired
UserRepository userRepository;
@Autowired
UserCommandService userCommandService;
@Test
public void registerUser() throws Exception {
//given
UserCommandDto userDto = new UserCommandDto("user");
//when
Long saveId = userCommandService.register(userDto);
User findUser = userRepository.findById(saveId).orElseThrow();
//then
Assertions.assertThat(findUser.getName()).isEqualTo(userDto.getName());
}
@Test
public void updateUser() throws Exception {
//given
User user = new User("nakim");
userRepository.save(user);
User findUser = userRepository.findById(user.getId()).orElseThrow();
UserCommandDto userCommandDto = new UserCommandDto("change name");
//when
userCommandService.update(findUser.getId(), userCommandDto);
//then
Assertions.assertThat(findUser.getName()).isEqualTo("change name");
}
@Test
public void deleteUser() throws Exception {
//given
User user1 = new User("user1");
User user2 = new User("user2");
User user3 = new User("user3");
userRepository.save(user1);
userRepository.save(user2);
userRepository.save(user3);
User findUser1 = userRepository.findById(user1.getId()).orElseThrow();
User findUser2 = userRepository.findById(user2.getId()).orElseThrow();
User findUser3 = userRepository.findById(user3.getId()).orElseThrow();
//when
Assertions.assertThat(userRepository.count()).isEqualTo(3);
userCommandService.delete(findUser1.getId());
userCommandService.delete(findUser2.getId());
//then
Assertions.assertThat(userRepository.count()).isEqualTo(1);
}
테스트는 독립적으로 되야 한다고 얼핏 들었다. 그런데 registerUser를 하면 객체가 새로 생성 되는데
위의 테스트에선 repository 계층에 의존적이다. 그래서 구글링을 해보니 mockito를 사용해서 mock객체
repository를 사용 할때 가짜 객체를 만들어서 테스트 하는게 있었는데 하다가 Error...에다가 그렇게 하는건지도 모르겠어서 오후내내 뚝딱뚝딱 하다가 말았다. 테스트란 개념을 이번에 java를 하면서 처음 해보는거라 생각나는대로 하고 있는데 이것도 규칙이 있던데 일단 만들어 놓고 보강 하도록 해야겠다.
인터넷 강의, 책만 보다가 스스로 무언가를 해보니 재밌다. 그런데 잘은 못한다. 하지만 기록은 남겨야지!