Blog GDSC CAU 개발자와 디자이너의 작업 과정과 결과물을 공유하는 공간입니다.
어떻게 프로젝트를 시작하게 되었고, 진행하면서 느낀 개발자와 디자이너의 생생한 스토리를 직접 확인해보세요!
Designed by Sohyun Kim, Serin Seong Developed by Yeojin Kim, Jiwoo Park, Yujin Son, Yongmin Yoo, Junesung Jang
Development 2주차 Spring Study #Back-End Yejin Jang 2023. 11. 28.
2주차 Spring Study
스터디 날짜 및 장소
지난주 스터디
스터디 내용
테스트 코드 작성 테스트 코드 없이 개발하는 경우 코드 작성 프로그램 실행 API 테스트 도구로 HTTP 요청 요청결과를 System.out.println()으로 검증 결과가 다르면 프로그램 중지하고 코드 수정 → 2~5번 과정을 코드 수정할 때마다 반복
테스트 코드의 장점 개발 초기 단계에 문제 발견 가능 나중에 코드 리팩토링 또는 라이브러리 업그레이드 등에서 기존 기능이 올바르게 작동하는지 확인 가능 기능에 대한 불확실성 감소 시스템에 대한 실제 문서 제공
test>DemoApplicationTests.java 생성
.andExpect(status().isOk()) mvc.perform의 결과 검증
HTTP Header의 Status 검증
롬복 설치 및 코드 전환 롬복 Java를 개발할 때 자주 사용하는 코드를 어노테이션으로 자동 생성해준다.
ex) getter, setter, 기본생성자, toString 등
HelloController 코드를 롬복으로 전환
롬복으로 변경했을 때 문제가 생기는지 테스트 코드를 돌려보면 알 수 있다.
문제 발생 여부 확인하는 코드 src>main>java>com.example.demo>web>dto 패키지생성>HelloResponseDto.java 생성
@Getter @RequiredArgsConstructor 선언된 모든 final 필드가 포함된 생성자를 생성
final이 없는 필드는 생성자에 포함되지 않는다.
test>java>com.example.demo>dto패키지 생성>HelloResponseDtoTest.java 생성
assertThat
HelloController에도 새로 만든 ResponseDto를 사용할 수 있도록 코드 추가
HelloControllerTest.java
param API 테스트 시 사용될 요청 파라미터 설정
값은 String만 허용
jsonPath JSON 응답값을 필드별로 검증할 수 있는 메소드
“$”를 기준으로 필드명 명시
해당 코드를 실행하면 JSON이 리턴되는 API도 정상적으로 테스트 통과하는 것을 확인할 수 있다.
package com.example.demo.web;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
package com.example.demo.web.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
package com.example.demo.web;
import com.example.demo.web.web.HelloController;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = HelloController.class)
public class DemoApplicationTests {
@Autowired
private MockMvc mvc;
@Test
public void return_hello() throws Exception{
String hello = "hello";
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string(hello));
}
}
dependencies{
implementation('org.projectlombok:lombok')
annotationProcessor('org.projectlombok:lombok')
testImplementation('org.projectlombok:lombok')
testAnnotationProcessor('org.projectlombok:lombok')
}
package com.example.demo.web.web.dto;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public class HelloResponseDto {
private final String name;
private final int amount;
}
package com.example.demo.web.dto;
import com.example.demo.web.web.dto.HelloResponseDto;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
public class HelloResponseDtoTest {
@Test
public void lombokTest(){
String name = "test";
int amount = 1000;
HelloResponseDto dto = new HelloResponseDto(name,amount);
assertThat(dto.getName()).isEqualTo(name);
assertThat(dto.getAmount()).isEqualTo(amount);
}
}
package com.example.demo.web.web;
import com.example.demo.web.web.dto.HelloResponseDto;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
@GetMapping("/hello/dto")
public HelloResponseDto helloDto(@RequestParam("name") String name, @RequestParam("amount") int amount) {
return new HelloResponseDto(name, amount);
}
}
package com.example.demo.web;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest
public class HelloControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void return_hello() throws Exception{
String hello = "hello";
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string(hello));
}
@Test
public void return_helloDto() throws Exception{
String name = "hello";
int amount = 1000;
mvc.perform(
get("/hello/dto")
.param("name",name)
.param("amount",String.valueOf(amount)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name",is(name)))
.andExpect(jsonPath("$.amount",is(amount)));
}
}