- 시작하게 된 계기 및 다짐 😮
이번 코드스테이츠의 백엔드 엔지니어링 개발자 부트캠프
에 참여하게 되면서 현직개발자 분들의 빠른 성장을 위한 조언 중 자신만의 블로그를 이용하여 배운 것 들을 정리하는게 많은 도움이 된다 하여 시작하게 되었다.
- 학습 목표 😮
목표 | 결과 |
---|---|
단위테스트 이해 및 적용 방법학습 | O |
Junit 사용 및 미사용 적용 방법 | O |
Hamcrest이해 및 사용 | O |
Slicing Test 이해 및 적용 방법 학습 | O |
Mockito 및 TDD 이해 | O |
- 정리 😮
1. 단위 테스트(Unit Test)
단위테스트란
단위테스트를 위한 F.I.R.S.T 원칙
1). Fast
2). Independent
3). Repeatable
4). Self-vaildating
5). Timely
2. JUnit없이 비지니스 로직에 단위 테스트 적용
Given-When-Then 표현 스타일
1). Given
2). when
3). Then
Extra
유틸리티 클래스
Assertion
0. @애너테이션
@Test
@DisplayName(" Tst " )
@BeforeEach
@BeforeAll
@AfterEach, AfterAll
1. JUnit 이해
JUnit
JUnit 작성법
Assertion 메서드
1). assertEquals(expected, actual)
2). assertNotNull(변수,"should be not null");
3). assertThrows(NullPointerException.class, () -> getCryptoCurrentcy("XRP"))
4). assertDoesNotThrow(()->getCryptoCurrency("XRP"))
5). assertThat(totalActual,is(total));
Assumption을 이용한 테스트
1). assumeTrue(System.getProperty("os.name").startsWith("Windows"));
Extra
1. Hamcrest
Hamcrest란
Hamcrest 메소드
1). assertThat(actual, is(equalTo(expected)));
[예제 Code]
Throwable actualException = assertThrows(NullPointerException.class,
() -> getCryptoCurrency("XRP")); // (1)
assertThat(actualException.getCause(), is(equalTo(null)));
3). Custom Matcher
[예제 Code]
public class IsNotANumber extends TypeSafeMatcher {
@Override
public boolean matchesSafely(Double number) {
return number.isNaN();
}
public void describeTo(Description description) {
description.appendText("not a number");
}
public static Matcher notANumber() {
return new IsNotANumber();
}
}
assertThat(Math.sqrt(-1), is(notANumber()));
Extra
Hamcrest의 다양한 Matcher
Hamcrest의 Custom Matcher 구현
0. @애너테이션
SpringApplication
List
@SpringBootTest
@AutoConfigureMockMvc
@DataJpaTest
1. SliceTest
슬라이스 테스트
Controller 테스트를 위한 클래스 구조 구성
1). MockMvc
Tomcat같은 서버를 실행하지 않고, Controller를 테스트할 수 있는 환경을 지원하는 Spring MVC 테스트 프레임워크
이를 통해 작성한 Controller를 호출해서 손쉽게 테스트 가능
(1) mockMvc.perfom()
(2) post()
(3) accept()
(4) contentType()
(5) content()
(6) andExpect(status().isCreated())
(6-1) andExpect(jsonPath("$.data.name").value(post.getName()))
(7) andReturn();
2). @AutoConfigureMockMvc , @SpringBootTest(SpringbootApplication을 찾아 테스트를 위한 빈들을 생성)
[MemberController 예제 Code]
@SpringBootTest
@AutoConfigureMockMvc
class MemberControllerTest2 {
@Autowired
private MockMvc mockMvc;
@Autowired
private Gson gson;
@Test
void postMemberTest() throws Exception {
// given
MemberDto.Post post = new MemberDto.Post("hgd@gmail.com",
"홍길동",
"010-1234-5678");
String content = gson.toJson(post);
// when
ResultActions actions =
mockMvc.perform(
post("/v11/members")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(content)
);
// then
MvcResult result = actions
.andExpect(status().isCreated())
.andExpect(jsonPath("$.data.email").value(post.getEmail())) // (1)
.andExpect(jsonPath("$.data.name").value(post.getName())) // (2)
.andExpect(jsonPath("$.data.phone").value(post.getPhone())) // (3)
.andReturn();
System.out.println(result.getResponse().getContentAsString());
}
}
Gson 라이브러리
1). gson.toJson(post)
Extra
스모크 테스트
MockMvc
MockMvc의 request수행 메서드들
MockMvcResultMatchers와 jsonPath()
@DataJpaTest
0. @애너테이션/정보
0. @애너테이션
@MockBean
@Mock
@ExtendWith(MockitoExtension.class)
@InjectMocks
1. Mockito란
Mock 이란
Mockito란
Code 리뷰
1). given(Controller 메서드 변수)
2). Mockito.any(Member.class)
3). will.return(member)
[예제 Code]
given(memberService.createMember(Mockito.any(Member.class)))
.willReturn(member);
Extra
Stubbing
Mockito 사용법
1. TDD란
TTD
TTD 장/단점
1) 장점
테스트를 통과 할 만큼의 기능을 구현하므로 한번에 너무 많은 기능을 구현할 필요가 없습니다.
테스트의 코드가 추가되면서 검증하는 범위가 넓어질 수록 기능 구현도 점진적으로 완성되어 갑니다.
즉, 단순한 기능에서 복잡한 기능으로 확장 되면서 그때 그때 검증을 빼먹지 않고 할 수 있습니다.
리팩토링 할 부분이 눈에 보이면 그때 그때 리팩토링을 빠르게 진행하기 때문에 리팩토링의 비용이 상대적으로 적어집니다.
리팩토링을 통해 꾸준히 코드를 개선하므로 코드의 품질을 일정 부분 유지할 수 있습니다.
코드 수정 이 후, 바로 테스트를 진행할 수 있으므로 코드 수정 결과를 빠르게 피드백 받을 수 있습니다.
즉, 수정 결과를 그때 그때 확인할 수 있으므로 잘못된 코드가 남아있을 가능성이 상대적으로 줄어듭니다.
2). 단점
Extra
- 피드백 😮
유닛 테스트의 경우, Hamcrest나 Assertion을 통하여 특정 기능(메소드 단위)로 측정하는 방법이다.
슬라이싱 테스트의 경우, Mockito(가짜객체)를 사용하지 않으면 뜻하지 않게 DB쪽을 사용하게 되어 Mockito객체를 사용하여 해당 계층(Layer)만을 테스트 할 수 있음
- 앞으로 해야 될 것 😮