일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 테스트메소드
- foreignkey
- appspec.yml
- querydsl
- 네이티브쿼리
- ㅔㄴ션
- 검색
- 서브쿼리
- 참조키
- 외부키
- appspec
- docker명령어
- 메소드명
- 메세지수정
- 포트
- 컨테이너실행
- ubuntu
- 2 > /dev/null
- AuthenticationEntryPoint
- Query
- 커밋메세지수정
- WeNews
- 적용우선순위
- EC2
- application.yml
- 테스트
- 예약
- MySQL
- subquery
- 추후정리
- Today
- Total
제뉴어리의 모든것
[Section3] [Spring MVC] 테스팅(Testing) - 4 (Mockito) Service 계층에 Mockito 이용 테스트 본문
[Section3] [Spring MVC] 테스팅(Testing) - 4 (Mockito) Service 계층에 Mockito 이용 테스트
제뉴어리맨 2022. 9. 18. 13:22깃 허브 주소
https://github.com/JanuaryKim/JanuaryKim-be-template-testing
- build.gradle
plugins {
id 'org.springframework.boot' version '2.7.1'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.codestates'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'com.google.code.gson:gson:2.9.0'
}
tasks.named('test') {
useJUnitPlatform()
}
- 검증하려는 Service 계층의 코드
@Transactional
@Service
public class MemberService {
private final MemberRepository memberRepository;
private final ApplicationEventPublisher publisher;
public MemberService(MemberRepository memberRepository,
ApplicationEventPublisher publisher) {
this.memberRepository = memberRepository;
this.publisher = publisher;
}
public Member createMember(Member member) {
verifyExistsEmail(member.getEmail()); // (1)
Member savedMember = memberRepository.save(member);
publisher.publishEvent(new MemberRegistrationApplicationEvent(this, savedMember));
return savedMember;
}
...
...
private void verifyExistsEmail(String email) {
Optional<Member> member = memberRepository.findByEmail(email); // (2)
// (3)
if (member.isPresent())
throw new BusinessLogicException(ExceptionCode.MEMBER_EXISTS);
}
}
검증하려는 부분은 (1), (2) 를 거쳐서 결국 (3)부분의 로직이다.
즉, 가입 요청을 하는 사람의 이메일과 동일한 이메일을 가진 멤버가 존재하다면 예외를 발생시키겠다는것이다.
- 테스트코드
import com.codestates.exception.BusinessLogicException;
import com.codestates.member.entity.Member;
import com.codestates.member.repository.MemberRepository;
import com.codestates.member.service.MemberService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.BDDMockito.given;
// (1)
@ExtendWith(MockitoExtension.class)
public class MemberServiceMockTest {
@Mock // (2)
private MemberRepository memberRepository;
@InjectMocks // (3)
private MemberService memberService;
@Test
public void createMemberTest() {
// given
Member member = new Member("hgd@gmail.com", "홍길동", "010-1111-1111");
// (4)
given(memberRepository.findByEmail(member.getEmail()))
.willReturn(Optional.of(member)); // (5)
// when / then (6)
assertThrows(BusinessLogicException.class, () -> memberService.createMember(member));
}
}
(1) : Mockito에서 지원하는 기능을 해당 클래스에서 사용하기 위한 애노테이션
쉽게 말해, org.mockito 패키지의 @Mock, @InjectMocks 같은 애노테이션을 사용하겠다는 것이다.
(2) : 가짜 객체를 만든다.
@MockBean과 같이 가짜 객체를 만든다는 점은 같지만,
@MockBean은 @SpringBootTest 와 함께 쓰여야 하며, (현재 코드의 MemberServiceMockTest에서 @MockBean으로 MemberService의 의존성 주입을 받으려고 해도, 객체 조차 만들어지지 않는다)
가짜 객체를 만들어 스프링컨테이너에 빈으로 등록하지만,
@Mock은 그냥 가짜 객체만 만들어 주는것이다.
그래서
@SpringBootTest 환경에서는 @Mock, @MockBean 모두 사용 가능.
@SpringBootTest 아닌 환경에서는 @Mock 가능, @MockBean 불가능이다. (스프링 컨테이너가 존재하지 않으면 @MockBean 으로 객체조차 주입되지 않고 null이 된다)
(3) : @Mock 애노테이션이 붙어서 가짜 객체가 만들어진 것들 중 의존성주입에 필요한 객체들을 의존성 주입 받겠다는 것이다.
그러므로, memberService 객체에는 (2)에서 @Mock으로 의존성 주입된 memberRepository가 주입되게 된다.
(4), (5) : 아무런 필드와 메소드를 가지지 않은 빈 껍데기인 memberRepository에 findByEmail() 메소드의 Input, Output을 정해준다.
(6) : 실제 검증부분으로써
두번째 인자인 ()-> memberService.createMember(member) 해당 구분 진행시,
BusinessLogicException.class 예외가 발생 될것임을 예상한다는 것이다.
'코드스테이츠 > 정리 블로깅' 카테고리의 다른 글
[Section 4] [인증/보안] 기초 (1) | 2022.09.21 |
---|---|
[Section3]기술 면접 (0) | 2022.09.19 |
[Section3] [Spring MVC] 테스팅(Testing) - 3 (Mockito) Service 계층을 끊은 Controller 테스트 (0) | 2022.09.17 |
[Section3] [Spring MVC] 테스팅(Testing) - 3 (데이터 액세스 계층 테스트) (0) | 2022.09.17 |
[Section3] [Spring MVC] 테스팅(Testing) - 2 (API 계층 테스트) (0) | 2022.09.17 |