mybatis - ID로 회원 조회 / TDD - jUnit Params
test 코드 작성
- MemberServiceTest
@Test
@DisplayName("ID로 회원 조회 테스트")
public void findMemberByIdTest() {
String userId = "admin2";
// service에서 findMemberById(userId)를 조회하고 memebr로 가져오기
Member member = service.findMemberById(userId);
// 검증 코드
// null이 아니라는 것을 예측하고 작성(실제 DB에 amdin2 계정 존재)
assertThat(memebr).isNotNull();
}
service 코드 작성
- test 코드에서 작성한 findMemberById() 메서드 작성
public Member findMemberById(String id) {
return null;
}
일단 이렇게 작성해서 test 코드의 에러만 없애주고 테스트를 진행해본다.
test에서는 isNotNull()을 작성했기 때문에 테스트가 통과되지 않는다.
-
public Member findMemberById(String id) {
return new Member();
}
이렇게 작성하면 Member를 리턴하기 때문에 테스트는 통과된다.
null이 아닌 게 맞기 때문에.
-
public Member findMemberById(String id) {
Member member = null;
// 쿼리문의 정보를 알고 있는 SqlSession 객체
SqlSession session = getSession();
// dao에 요청. session과 id를 넘겨줌
member = dao.findMemberById(session, id);
session.close();
return member;
}
그 후에 service 코드의 리팩토링을 진행했다.
이렇게 작성하고 에러를 지워주기 위해 dao에도 findMemberById() 메서드를 작성한다.
dao 작성
- service에서 넘겨 받은 findMemberById() 메서드 작성
public Member findMemberById(SqlSession session, String id) {
// return null;
return new Member();
}
일단 이렇게 작성하고 테스트 통과 여부를 확인한다.
null / new Member() 모두 확인.
-
public Member findMemberById(SqlSession session, String id) {
// id : 두번째 매개값은 쿼리문에서 사용될 파라미터 객체
return session.selectOne("memberMapper.selectMemberById", id);
}
테스트 통과가 잘 되었으면 dao도 리팩토링 진행하기.
session 객체를 통해 쿼리문을 실행시키고 결과값을 받아올 거임.
id로 조회하면 resultSet이 하나이기 때문에 selectOne을 사용.
-
- memberMapper : namespace
- selectMemberById : 쿼리문의 id
- id : service에서 받은 id
쿼리문 작성
- member-mapper.xml
<!--
id="selectMemberById" : dao에서 지정해둔 id와 일치하게 작성
parameterType="string" : 외부에서 매개변수로 받는 값이 있을 경우 타입 지정 필수(소문자인 이유 : mybaits에서 제공하는 자료형 별칭)
resultMap="memberResultMap" : enroll_date 같이 필드명과 컬럼명이 달라 자동 매칭이 안되는 것을 해결하기 위해 만들어둔 것 사용
#{id} : dao에서 받은 매개변수
-->
<select id="selectMemberById" parameterType="string" resultMap="memberResultMap">
SELECT NO,
ID,
PASSWORD,
ROLE,
NAME,
PHONE,
EMAIL,
ADDRESS,
HOBBY,
STATUS,
ENROLL_DATE,
MODIFY_DATE
FROM MEMBER
WHERE ID = #{id} AND STATUS = 'Y'
</select>
테스트 통과.
selectOne은 selectList와 다르게
만약 테스트 코드에서 작성한 userId admin2이 없거나
STATUS가 N일 경우 테스트는 실패한다. (List는 빈 리스트를 리턴함)
-
-참고-
<select id="selectMemberById" parameterType="map" resultMap="memberResultMap">
SELECT NO,
ID,
PASSWORD,
ROLE,
...
...
FROM MEMBER
WHERE ID = #{id} AND STATUS = 'Y'
</select>
parameterType을 map으로 지정해도 테스트 통과됨.
이렇게 지정해도 파라미터를 넘길 때 변수명 id를 키값으로 갖는 map 형태로 준다고 합니다..(?)
다음에 더 설명해주신다고 함..
여러 id를 파라미터로 넘기기
- 위에서는 admin2 <- 하나의 계정으로만 테스트가 가능했다. 여러 계정을 넘길 수 있도록 test 코드를 리팩토링 한다.
-
1) jUnit 라이브러리 추가
- maven repository에서 jUnit 검색
-
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
- pom.xml에 jUnit Params 최신 버전 추가
-
- update maven 하고 Dependencies에 추가되었는지 확인
-
2) Annotation 추가
// @Test // 기존 사용했던 annotation 삭제
@ParameterizedTest // 방금 추가한 라이브러리에서 제공하는 annotation(jupiter-params)
@ValueSource(strings = {"admin1", "admin2"}) // userId를 매개값으로 추가
@DisplayName("ID로 회원 조회 테스트")
public void findMemberByIdTest(String userId) {
// String userId = "admin1"; // valuseource에 추가했기 때문에 삭제
Member member = service.findMemberById(userId);
assertThat(member).isNotNull() // 실제 위에 두 계정이 존재하기 때문에 null이 아니고
.extracting("id") // member 객체에서 id만 추출하고
.isEqualTo(userId); // 추출한 것과 매개값으로 넘긴 id가 일치하는지 확인
}
valueSource에 있는 매개값을 하나씩 넘겨주기 위해 ParameterizedTest 어노테이션 사용!
둘이 세트라고 생각하자..
아 그리고 매개값의 개수만큼 테스트를 진행하게 된다.
와 진짜 코드 작성하고 강사님이 해주는 말 필기하기 바쁘다 바빠…
갑자기 파일도 많아져서 수업 때 너무 힘들었다.
이 파일, 저 파일 왔다리 갔다리……… 댑악.