24.03.05

서린·2024년 3월 5일

혼자개발

목록 보기
61/82

JUnit test
UserRestController에 대한 테스트를 진행해보려고 한다

먼저 아이디 중복 확인 메소드

/**
* 아이디 중복확인
* @param loginId
* @return
*/
@RequestMapping("/is-duplicated-id")
public Map<String, Object> isDuplicatedId(
	@RequestParam("loginId") String loginId) {
		
		//db 조회
		UserEntity user = userBO.getUserEntityByLoginId(loginId);
		
		//응답값 만들고 return-> json
		Map<String, Object> result = new HashMap<>();
		result.put("code", 200);
		
		if (user == null) {
			//중복 아닐때
			result.put("isDuplicated", false);
		} else {
			//중복일 때
			result.put("isDuplicated", true);
		}
		return result;
		
	}

test 코드

@AutoConfigureMockMvc
@SpringBootTest
class UserRestControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Mock
    private UserBO userBO;

    @InjectMocks
    private UserRestController userRestController;
    
    @Test
    void 아이디중복확인테스트_중복되지않는경우() throws Exception {
        // Given
        String loginId = "exampleId";

        // Mocking the userBO response
        when(userBO.getUserEntityByLoginId(anyString())).thenReturn(null);

        // When
        Map<String, Object> result = userRestController.isDuplicatedId(loginId);

        // Then
        assertEquals(200, result.get("code"));
        assertFalse((boolean) result.get("isDuplicated"));
    }

    @Test
    void 아이디중복확인테스트_중복되는경우() throws Exception {
        // Given
        String loginId = "exampleId";
        UserEntity mockUserEntity = UserEntity.builder()
                .id(1)
                .name("Example User")
                .loginId(loginId)
                .build();

        // Mocking the userBO response
        when(userBO.getUserEntityByLoginId(anyString())).thenReturn(mockUserEntity);

        // When
        Map<String, Object> result = userRestController.isDuplicatedId(loginId);

        // Then
        assertEquals(200, result.get("code"));
        assertTrue((boolean) result.get("isDuplicated"));
    }
}

✅ 테스트 성공

@AutoConfigureMockMvc 어노테이션은 Spring Boot 테스트에서 MockMvc를 수동으로 구성 할 필요 없이 자동으로 구성하도록 하는 역할.
이 어노테이션을 사용하면 테스트 클래스에서 MockMvc를 @Autowired로 주입받아서 사용할 수 있다
MockMvc는 Spring MVC 애플리케이션을 테스트하는 데 사용되는 클래스로, HTTP 요청을 모의로 보내고 컨트롤러의 응답을 검증할 수 있다

Mockito를 사용하여 UserBO의 메소드 호출을 가로채어 가짜 응답을 반환하도록 설정
Mockito를 사용하여 UserBO의 getUserEntityByLoginId 메소드가 호출될 때 원하는 결과를 반환하도록 설정하고, UserRestController의 isDuplicatedId 메소드를 호출하여 반환된 결과를 검증

Mockito를 사용하는 이유?
1. 의존성 제어, 격리 : 의존성을 가짜 객체로 대체하여 해당 클래스의 동작을 격리 시킬 수 있다 -> 테스트의 안정성과 신뢰성 높일 수 있음
2. stubbing : 메소드의 반환값을 가짜로 설정할 수 있다, 테스트 시나리오에 따라 특정 메소드가 어떤 값을 반환하도록 조작할 수 있다 -> 다양한 상황에서의 테스트를 수행 할 수 있음
3. 검증 : 메소드가 정확한 매개변수로 호출되었는지를 확인하거나, 메소드 호출 횟수를 검증할 수 있다

회원가입 테스트

/**
	 * 회원가입
	 * @param loginId
	 * @param password
	 * @param name
	 * @param email
	 * @return
	 */
	@PostMapping("/sign-up")
	public Map<String, Object> signUp(
			@RequestParam("loginId") String loginId,
			@RequestParam("password") String password,
			@RequestParam("name") String name,
			@RequestParam("email") String email) {
		
		//password 해싱 - md5알고리즘
		String hashedPassword = PasswordEncoder.encode(password);
		
		//db insert
		Integer id = userBO.addUser(loginId, hashedPassword, name, email);
		
		//응답값
		Map<String, Object> result = new HashMap<>();
		
		if (id == null) {
			result.put("code", 500);
			result.put("errorMessage", "회원가입에 실패했습니다");
		} else {
			result.put("code", 200);
			result.put("result", "성공");
		}
		return result; 
	}

test 코드

 @Transactional
    @Test
    void 회원가입_테스트() throws Exception {
        // Given
        String loginId = "exampleId";
        String password = "examplePassword";
        String name = "Example User";
        String email = "example@example.com";

        String hashedPassword = PasswordEncoder.encode(password);
        Integer userId = 1; // 예시로 사용자 ID를 지정합니다.

        // Mocking the userBO response
        when(userBO.addUser(anyString(), anyString(), anyString(), anyString())).thenReturn(userId);

        // When & Then
        mockMvc.perform(post("/user/sign-up")
                .param("loginId", loginId)
                .param("password", password)
                .param("name", name)
                .param("email", email))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.result").value("성공"));
    }

회원가입 성공 테스트는 테스트 성공했지만 회원가입 실패 테스트는 자꾸 회원가입이 성공해서 테스트가 실패했다.

@Transactional
    @Test
    void 회원가입_실패_테스트() throws Exception {
    	 // Given
        String loginId = "testUser";
        String password = "examplePassword";
        String email = "example@example.com";
        String name = "";

        // When & Then
        mockMvc.perform(post("/user/sign-up")
                .param("loginId", loginId)
                .param("password", password)
                .param("email", email)
                .param("name", name))
        		.andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(400))
                .andExpect(jsonPath("$.errorMessage").value("이름을 입력하세요"))
                .andExpect(jsonPath("$.result").doesNotExist()); 
    }
    

회원가입이 실패 할 수 있는 조건을 생각하다가
필수로 제공되어야 하는 정보가 제공되지 않으면 실패조건을 만들 수 있겠다고 생각했다

처음엔 name을 String name = "null"; 로 제공했더니
null이 string으로 인식되어 회원가입이 성공해 테스트 실패

String name = null;로 제공해도 실패

String name = ""; 로 제공해도 실패
sign-up.jsp를 확인 해봐도 !name일 때 회원가입이 되지 않도록 되어있는데,,
그래서 name의 유효성 검사가 필요하다고 판단해
userRestController에 추가해줬다

/**
	 * 회원가입
	 * @param loginId
	 * @param password
	 * @param name
	 * @param email
	 * @return
	 */
	@PostMapping("/sign-up")
	public Map<String, Object> signUp(
			@RequestParam("loginId") String loginId,
			@RequestParam("password") String password,
			@RequestParam("name") String name,
			@RequestParam("email") String email) {
		
		 // 이름에 대한 유효성 검사 수행
	    if (name.isEmpty()) {
	        Map<String, Object> result = new HashMap<>();
	        result.put("code", 400);
	        result.put("errorMessage", "이름을 입력하세요");
	        return result;
	    }
		
		//password 해싱 - md5알고리즘
		String hashedPassword = PasswordEncoder.encode(password);
		
		//db insert
		Integer id = userBO.addUser(loginId, hashedPassword, name, email);
		
		//응답값
		Map<String, Object> result = new HashMap<>();
		
		if (id == null) {
			result.put("code", 500);
			result.put("errorMessage", "회원가입에 실패했습니다");
		} else {
			result.put("code", 200);
			result.put("result", "성공");
		}
		return result; 
	}

유효성 검사를 추가해주니 회원가입이 실패되고 테스트가 성공했다

✅ 테스트 성공

0개의 댓글