1편에서
https://iamipro.tistory.com/502
사실 Test 인 Junit 빼고는 나머지는 익히 다 안것이었다.
개발을 TDD로 해본적이 없어서 저번 항해플러스에서 많이 애먹었는데
백엔드 입문 기본에 TDD식 기본이 나온다.
@AutoConfigureMockMvc
@SpringBootTest
class BlogApiControllerTest {
MockMVC만드는 거랑 설정
@Autowired
protected MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
BlogRepository blogRepository;
@BeforeEach
public void mockMvcSetUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
blogRepository.deleteAll();
}
MockMvcBuilders가 WebApplicationContext 가지고 셋업까지 한다.
이런식으로 Mock을 써본 것도 처음인것 같다.
라이브러리도 Hamcrest라고 표현식을 보다 쉽게 만드는데 사용되는 Matcher 라이브러리를 새로 봤고, 그외 JUnit, SpringBootTest, AssertJ, Mockito, JSONassert, JsonPath 이런 것들은 다 한번씩 본것 같다.
이런 형태로 객체를 String으로 직렬화 하는 것과, 직렬화의 개념을 좀더 명확히 알게 된 것이 좋았다.
final AddArticleRequest addArticleRequest = new AddArticleRequest(title, content);
// 직렬화
final String requestBody = objectMapper.writeValueAsString(addArticleRequest); // 객체를 json 문자열로 직렬화
post, get으로 통신하는 것...
// 설정한 내용을 바탕으로 요청 전송
ResultActions resultActions = mockMvc.perform(post(url)
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody));
// when
final ResultActions resultActions = mockMvc.perform(get(url, article.getId()));
jsonPath로 확인하는 것
resultActions.andExpect(status().isOk())
.andExpect(jsonPath("title").value(title))
.andExpect(jsonPath("content").value(content));
assertThat을 쓰기 까지 과정
// given
final String url = "/api/article/{id}";
final String title = "제목";
final String content = "내용";
Article article = blogRepository.save(Article.builder().title(title).content(content).build());
// when
mockMvc.perform(delete(url, article.getId())).andExpect(status().isOk());
// then
List<Article> articles = blogRepository.findAll();
assertThat(articles).isEmpty();
CRUD는 그냥 기본적으로 탑재해서 만들어 봤는데
이렇게 TDD형태로 테스트 하는 건 해봤지만 익숙하지 않다.
그냥 작동하는 거 보고 되면 넘어갔는데...
후반에 가면 좀더 고차원적인 테스트가 나타날려나...
지금 보이는건 그저 http통신이 되고 인자만 맞다면 직관적으로..
제대로 작동할 것 같은 테스트다...
h2 db 에서 data.sql 을 넣기 위해서 아래와 같이
defer-datasource-initialization: true 해줘야 하고
spring:
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
defer-datasource-initialization: true
datasource:
url: jdbc:h2:mem:blog
h2:
console:
enabled: true
그외 dto를 빌더패턴으로 하던가..
참으로 restful하게 자원을 명사적으로 잘 알아보게 만들어놨다.
article을 복수로 하는게 맞긴 하는데 그냥 이대로도 나쁘지 않은 것 같아서..
단수를 쓰긴 했는데 신경써야 하는 생각이 문득 들기는 하는데...
궂이 구분을 해보면 한군데 복수로 써야 하는 곳이 있기는 하다.
그러나 그냥 코드 보기 편하게... pass
@PostMapping("/api/article")
public ResponseEntity<Article> addArticle(@RequestBody AddArticleRequest request) {
Article savedArticle = blogService.save(request);
return ResponseEntity.status(HttpStatus.CREATED).body(savedArticle);
}
@GetMapping("/api/article")
public ResponseEntity<List<ArticleResponse>> findAllArticles() {
List<ArticleResponse> articles = blogService.findAll()
.stream()
.map(ArticleResponse::new)
.toList();
return ResponseEntity.ok().body(articles);
}
@GetMapping("/api/article/{id}")
public ResponseEntity<ArticleResponse> findArticleById(@PathVariable Long id) {
Article article = blogService.findById(id);
return ResponseEntity.ok().body(new ArticleResponse(article));
}
@DeleteMapping("/api/article/{id}")
public ResponseEntity<Void> deleteArticleById(@PathVariable Long id) {
blogService.deleteById(id);
return ResponseEntity.ok().build();
}
@PutMapping("/api/article/{id}")
public ResponseEntity<Article> updateArticle(@PathVariable Long id, @RequestBody UpdateArticleRequest request) {
Article updatedArticle = blogService.update(id, request);
return ResponseEntity.ok().body(updatedArticle);
}
Restful하게 하는것도 좀더 연습해야 겠다.
화면까지 가서 대충 타임리프 하나 만들어 놓긴 했는데..
뭐mvc야 그렇다 치고
@Getter
@Setter
class Person {
private Long id;
private String name;
private int age;
private List<String> hobbies;
}
요 dto를 아래와 같이 today 날짜랑 찍어주는 간단한 예제다.
타임리프도 오랜만에 보니 새록새록 재밌다. JSTL이 생각난다. 방식이 다르지만
'4차산업혁명의 일꾼 > Java&Spring웹개발과 서버 컴퓨터' 카테고리의 다른 글
자바의 희망 구독/서브모델의 Kafka , 대용량처리 관련 캐쉬하는 Redis, 장애예방 CircuitBreaker, 장애대응책 RetryConfig (0) | 2024.07.18 |
---|---|
스프링 기본개념과 변천사 그리고 스프링버전5이상 혹은 스프링부트3의 필요성에 관하여 (2) | 2024.07.13 |
스프링부트3 백엔드 개발자 되기(신선영 지음) - 1. 스프링부트 입문기초 (0) | 2024.06.25 |
자바8 , 11, 17 간단 정리 (1) | 2024.06.18 |
스프링 버전 4와 5의 차이 정리 (2) | 2024.06.18 |