백엔드

스프링 부트와 AWS로 혼자 구현하는 웹 서비스(-78p)

_JIONE_ 2023. 1. 6. 16:26
  1. 코드를 작성하고
  2. 프로그램(tomcat=server)를 실행한 뒤
  3. postman과 같은 API 테스트 도구로 HTTP 요청하고
  4. 요청결과를 System.out.println()으로 눈으로 검증한다.
  5. 결과가 다르면 다시 프로그램(tomcat)을 중지하고 코드를 수정한다.

=> 테스트 코드를 작성하면 이런 문제가 해결되므로 굳이 tomcat을 올렸다 내렸다 할 필요가 없다.

=> 테스트 코드를 작성하면 system.out.println()으로 확인할 필요없이 자동검증이 된다.

 

테스트 코드 작성을 도와주는 프레임워크들이 있다. 자바는 Junit을 사용한다.

 

 

HelloSpringApplication

클래스는 앞으로 만들 프로젝트의 메인 클래스가 된다.

 

@SpringBootApplication

으로 인해 스프링 부트의 자동 설정, 스프링 Bean 읽기와 생성을 모두 자동으로 설정해준다. 특히나 이 위치로부터 설정을 읽어가기 때문에 이 클래스는 항상 프로젝트의 최상단에 위치해야 한다.

 

SpringApplication.run

을 통해 내장 WAS가 실행되고, 이렇게 되면 톰캣을 설치할 필요가 없어지고 jar파일을 통해 서버가 실행된다.

=> 언제 어디서나 같은 환경에서 스프링 부트를 배포할 수 있게 된다.

 

 

① @RestController: 컨트롤러를 JSON을 반환하는 컨트롤러로 만들어 준다.

② @GetMapping: HTTP Method인 Get의 요청을 받을 수 있는 API를 만들어 준다.

 

 

롬북 소개 및 설치

: 자바 개발자들의 필수 라이브러리 롬북

 

롬북은 자바 개발할 때 자주 사용되는 코드 Getter, Setter, 기본생성자, toString 등을 어노테이션으로 자동 생성해준다.

인텔리제이에서는 build.gradle에 코드추가 + 플러그인을 통해 쉽게 설정 가능하다.

 

Getter과 Setter이 필요한 이유? 멤버 변수에 private를 설정하지 않으면 객체의 멤버 변수에 대해 무분별한 접근 및 수정을 막을 수 없어 보안과 안정성에서 큰 문제를 야기할 수 있다. 접근 방법으로 나온 어노테이션이 Getter와 Setter이다.

 

  • Getter
    • 멤버 변수의 값을 조회하기 위한 메서드
  • Setter
    • 멤버 변수에 값을 할당하기 위한 메서드

Lombok 사용 전 testDTO

public class testDTO {
	
	private String id;
	private String name;
	private int age;
	
	// getter/setter 생성
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
 
}

Lombok 사용 후 testDTO

import lombok.Getter;
import lombok.Setter;


//@Getter 이렇게 적으면 선언된 모든 필드에 get메소드를 적용
public class testDTO {
	
	private @Getter @Setter String id;
	private @Getter @Setter String name;
	private @Getter @Setter int age;
    
}

 

 

2.4 Hello Controller 코드를 롬북으로 전환하기

 

@Getter
@requiredArgsConstructor

public class HelloResponseDTO{
	private final String name;
    private final int amount;
}

① @requiredArgsConstructor: 선언된 모든 final 필드가 포함된 생성자를 생성해준다.

final 없는 필드는 생성자에 포함되지 않는다.

public class HelloResponseDtoTest {
	@Test
    public void 롬북_기능_테스트(){
    	//given
        String name = "test";
        int amount = 1000;
        
        //when
        HelloResponseDto dto = new HelloResponseDto(name,amount);
        
        //then
        assertThat(dto.getName()).isEqualTo(name);
        assertThat(dto.getAmount()).isEqualTo(amount);
    }
}

① assertThat: 테스트 검증 라이브러리의 검증 메소드로, 검증하고 싶은 대상을 메소드 인자로 받는다.

메소드 체이닝이 지원되어 isEqualTo와 같이 메소드를 이어서 사용할 수 있다.

isEqualTo: assertj의 동등 비교 메소드로, assertThat에 있는 값과  isEqualTo의 값을 비교해 같을 때만 성공이다.

@RestController
public class HelloController {
	
    @GetMapping("/hello/dto")
    public HelloResponseDto helloDto(@RequestParam("name") String name, @RequestParam("amount") String amount){
    	return new HelloResponseDto(name, amount);
    }
}

① @RestController: 컨트롤러를 JSON을 반환하는 컨트롤러로 만들어준다.

② @RequestParam: 외부에서 api로 넘긴 파라미터를 가져오는 어노테이션으로, 여기서는 외부에서 name(@RequestParam("name"))이란 이름으로 넘긴 파라미터를 메소드 파라미터 name(String name)에 저장한다.

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = HelloController.class)
public class HelloControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void hello가_리턴된다() throws Exception {
        String hello = "hello";

        mvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andExpect(content().string(hello));
    }
}

@RunWith(SpringRunner.class): 테스트를 진행할 때 JUnit에 내장된 실행자 외에 다른 실행자를 실행시킨다. 여기서는 SpringRunner라는 스프링 실행자를 사용한다. 즉, 스프링 부트 테스트와 JUnit 사이의 연결자 역할을 한다.

② @Autowired: 스프링이 관리하는 빈(자바 객체)을 주입받는다.

③  private MockMvc mvc: 웹 API를 테스트할 때 사용한다. 스프링 MVC 테스트의 시작점으로 이 클래스를 통해 HTTP  GET,POST 등에 대한 API 테스트를 진행할 수 있다.

④ mvc.perform(get("/hello")): MockMvc를 통해 /hello 주소로 HTTP GET 요청을 한다.

체이닝이 지원되어 아래와 같이 여러 검증 기능을 이어서 선언할 수 있다.

⑤ .andExpect(status().isOk()): mvc.perform의 결과를 검증한다. 흔히 알고 있는 200,404,500 등의 상태를 검증한다.

여기서는 OK, 즉 200인지 아닌지를 검증한다.

⑥ .andExpect(content().string(hello)): controller에서 "hello"를 리턴하기 때문에 이 값이 맞는지 검증한다.