비버놀로지

[Spring JPA] 1-7. 회원 가입 리펙토링 및 테스트 본문

LANGUAGE STUDY/Spring

[Spring JPA] 1-7. 회원 가입 리펙토링 및 테스트

KUNDUZ 2021. 4. 30. 21:06
728x90

먼저 지금까지 작성한 코드들을 테스트 하기위해 AccoutControllerTest를 수정해 줍니다.

 

	@DisplayName("회원 가입 처리 - 입력값 오류")
	@Test
	void signUpSubmit_with_wrong_input() throws Exception {
		mockMvc.perform(post("/sign-up").param("nickname", "keesun").param("email", "keesun@email.com")
				.param("password", "12345678").with(csrf()))

				.andExpect(status().isOk()).andExpect(view().name("account/sign-up"));
		
		assertTrue(accountRepository.existsByEmail("keesun@email.com"));
		then(javaMailsender).should().send(any(SimpleMailMessage.class));

	}

 

위의 코드를 추가를 해서 회원 가입을 할 때 에러가 나는지 확인을 해 줘야 합니다.

 

package com.studyolle.account.controller;

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;

import javax.mail.internet.MimeMessage;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.test.web.servlet.MockMvc;

import static org.mockito.BDDMockito.then;
import static org.mockito.ArgumentMatchers.any;
import com.studyolle.repository.AccountRepository;

@SpringBootTest
@AutoConfigureMockMvc
public class AccountControllerTest {

	@Autowired
	private MockMvc mockMvc;
	
	@Autowired
	private AccountRepository accountRepository;
	
	@MockBean
	JavaMailSender javaMailsender;

	@DisplayName("회원 가입 화면 보이는지 테스트")
	@Test
	void signUpForm() throws Exception {
		mockMvc.perform(get("/sign-up")).andDo(print()).andExpect(status().isOk())
				.andExpect(view().name("account/sign-up")).andExpect(model().attributeExists("signUpForm"));
	}

	@DisplayName("회원 가입 처리 - 입력값 오류")
	@Test
	void signUpSubmit_with_wrong_input() throws Exception {
		mockMvc.perform(post("/sign-up").param("nickname", "keesun").param("email", "keesun@email.com")
				.param("password", "12345678").with(csrf()))

				.andExpect(status().isOk()).andExpect(view().name("account/sign-up"));
		
		assertTrue(accountRepository.existsByEmail("keesun@email.com"));
		then(javaMailsender).should().send(any(SimpleMailMessage.class));

	}
}

 

 

위의 코드는 수정후 전체 코드 입니다.

 

그리고 지금까지 작성한 AccountController의 복잡한 구조를 해결하기 위해 Service를 만들어서 해결해 줍니다.

 

package com.studyolle.account.controller;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PostMapping;

import com.studyolle.account.service.AccountService;
import com.studyolle.repository.dto.SignUpForm;

import lombok.RequiredArgsConstructor;

@Controller
@RequiredArgsConstructor
public class AccountController {

	private final SignUpFormValidator signUpFormValidator;

	@Autowired
	AccountService accountService;

	@InitBinder("signUpForm")
	public void initBinder(WebDataBinder webDataBinder) {
		webDataBinder.addValidators(signUpFormValidator);
	}

	@GetMapping("/sign-up")
	public String signUpForm(Model model) {
		model.addAttribute("signUpForm", new SignUpForm());
		return "account/sign-up";
	}

	@PostMapping("/sign-up")
	public String signUpSubmit(@Valid SignUpForm signUpForm, Errors errors) {
		if (errors.hasErrors()) {
			return "account/sign-up";
		}
		accountService.processNewAccount(signUpForm);
		return "redirect:/";
	}


}

 

package com.studyolle.account.service;

import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import com.studyolle.repository.AccountRepository;
import com.studyolle.repository.dto.Account;
import com.studyolle.repository.dto.SignUpForm;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class AccountService {
	

	private final AccountRepository accountRepository;
	private final JavaMailSender javaMailSender;
	

	public void processNewAccount(SignUpForm signUpForm) {
		Account newAccount = saveNewAccount(signUpForm);
		sendSignUpConfirmEmail(newAccount);
	}
	
	public Account saveNewAccount(SignUpForm signUpForm) {
		Account account = Account.builder().email(signUpForm.getEmail()).nickname(signUpForm.getNickname())
				.password(signUpForm.getPassword()) // TODO encoding 해야됨
				.studyCreatedByWeb(true).studyEnrollmentResultByWeb(true).studyUpdatedByWeb(true).build();
		Account newAccount = accountRepository.save(account);

		newAccount.generateEmailCheckToken();
		return newAccount;
	}

	public void sendSignUpConfirmEmail(Account newAccount) {
		SimpleMailMessage mailMessage = new SimpleMailMessage();
		mailMessage.setSubject("스터디올래, 회원 가입 인증");
		mailMessage.setText(
				"/check-email-tocken?token=" + newAccount.getEmailCheckToken() + "&email=" + newAccount.getEmail());
		javaMailSender.send(mailMessage);
	}
}

 

위의 두 코드는 AccountController를 Service로 분리를 통해 좀더 간결하게 만든 후의 모습입니다.

 

이러한 리펙토링 과정을 통해서 컨트롤러에서는 좀더 간결하게 코드를 보여줄 수 있습니다.

 

 

 

728x90
Comments