본문 바로가기
뒤끝 (Back-End)

[Spring boot] Lombok, DTO 추가 / Test 코드 구조

728x90

개발환경

- Java 버전 : openjdk version "17.0.2"

- IntelliJ 버전 : IntelliJ IDEA Community 2023.03.06

- Springboot 버전 : 3.1.10

 

 

프로젝트 구성

 

 

main 폴더

 

TestspringbootApplication.java

package com.example.testspringboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// 프로젝트 최상단에 위치해야함
@SpringBootApplication
public class TestspringbootApplication {

	public static void main(String[] args) {
		SpringApplication.run(TestspringbootApplication.class, args);
	}

}

 

 

HelloController.java

package com.example.testspringboot.controller;

import com.example.testspringboot.controller.dto.HelloResponseDto;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController // @RestController : 컨트롤러를 JSON을 반환하는 컨트롤러로 만들어줌
public class HelloController {
    @GetMapping("/hello") // @GetMapping : HTTP Method인 Get의 요청을 받을 수 있는 API를 만들어 줌
    public String hello()
    {
        return "hello";
    }

    @GetMapping("/hello/dto")
    public HelloResponseDto helloDto(@RequestParam("name") String name, // @RequestParam : 외부에서 API로 넘긴 파라미터를 가져오는 어노테이션
                                     @RequestParam("amount") int amount)
    {
        return new HelloResponseDto(name, amount);
    }
}

 

@RestController : 컨트롤러를 JSON을 반환하는 컨트롤러로 만들어줌
@GetMapping : HTTP Method인 Get의 요청을 받을 수 있는 API를 만들어 줌
@RequestParam : 외부에서 API로 넘긴 파라미터를 가져오는 어노테이션

 

HelloResponseDto.java

package com.example.testspringboot.controller.dto;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter // @Getter : 선언된 모든 필드의 get 메소드를 생성해 줍니다
@RequiredArgsConstructor // @RequiredArgsConstructor : 선언된 모든 final 필드가 포함된 생성자를 생성
public class HelloResponseDto {
    private final String name;
    private  final int amount;

}

 

@Getter : 선언된 모든 필드의 get 메소드를 생성해 줍니다
@RequiredArgsConstructor : 선언된 모든 final 필드가 포함된 생성자를 생성

 

Test 코드 기본 구조 및 개념

 

Given: 테스트를 수행하기 위해 사전 조건을 설정하는 부분입니다. 주어진 상황이나 초기화 작업을 수행합니다. 이 부분에서는 테스트할 대상 객체를 생성하거나 초기화하고, 필요한 데이터를 설정합니다.

< 테스트 실행을 준비하는 단계 >

When: 주어진 상황에서 어떤 동작이 실행되는지를 정의하는 부분입니다. 테스트할 대상에 대해 어떤 특정한 동작이나 메소드 호출을 수행합니다. 이 단계에서는 특정한 행동 또는 동작을 발생시키는데 관심이 있습니다.

< 테스트를 진행하는 단계 >

Then: 특정한 조건이나 기대 결과를 검증하는 부분입니다. 테스트의 결과가 주어진 상황에서 예상한 대로 발생했는지를 확인합니다. 일반적으로 검증(assertion)을 사용하여 예상한 결과와 실제 결과를 비교합니다.

< 테스트 결과를 검증하는 단계 >

 

@Test
public void testLogin() {
    // Given
    User user = new User("username", "password");
    
    // When
    boolean result = userService.login(user);
    
    // Then
    assertTrue(result);
}

 

Given: 사용자 객체가 주어졌습니다. 이때는 특정한 사용자 객체를 생성하여 준비합니다.
When: UserService의 login 메소드가 호출되었습니다. 이때는 사용자가 제공한 정보를 사용하여 로그인을 시도합니다.
Then: 로그인 결과를 확인합니다. 이 테스트 케이스에서는 로그인이 성공했는지를 검증하고, assertTrue 메소드를 사용하여 결과를 확인합니다.
이렇게 Given-When-Then 패턴을 사용하면 테스트 코드의 목적이나 흐름을 명확하게 전달할 수 있으며, 코드를 이해하기 쉽고 유지보수하기 편리해집니다.

 

Test 폴더

 

TestspringbootApplicationTests.java

package com.example.testspringboot;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest 
class TestspringbootApplicationTests {

	@Test
	void contextLoads() {
	}

}

 

@SpringBootTest : 메인 애플리케이션 클래스에 추가하는 @SpringBootApplication 이 있는 클래스를 찾고 빈을 찾은 다음 테스트용 app컨텍스트 생성

 

HelloControllerTest.java

package com.example.testspringboot.controller;

import org.junit.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 org.springframework.test.web.servlet.ResultActions;

import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;



@RunWith(SpringRunner.class) // @RunWith : 스프링부트 테스트와 JUnit 사이에 연결자 역할
@WebMvcTest(controllers = HelloController.class) // Web Mvc에 집중할 수 있는 어노테이션 (@Controller, @ControllerAdvice 사용 가능)
public class HelloControllerTest {
    @Autowired // 스프링이 관리하는 빈을 주입
    private MockMvc mvc; // 웹 API를 테스트 할 때 사용, 테스트의 시작점

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

        mvc.perform(get("/hello")) // MockMvc를 통해 /hello 주소로 HTTP GET 요청을 한다
                .andExpect(status().isOk()) // HTTP Header의 Status를 검증
                .andExpect(content().string(hello)); // 응답 본문의 내용 검증
    }

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

        mvc.perform(get("/hello/dto")
                                .param("name", name) // param() : API 테스트 할 떄 사용될 요청 파라미터 설정
                                .param("amount", String.valueOf(amount)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name", is(name))) // jsonPath() : JSON 응답 값을 필드별로 검증할 수 있는 메소드, $ 기준으로 필드명 명시
                .andExpect(jsonPath("$.amount", is(amount)));
    }

}

 

@RunWith : 스프링부트 테스트와 JUnit 사이에 연결자 역할
@WebMvcTest : Web Mvc에 집중할 수 있는 어노테이션 (@Controller, @ControllerAdvice 사용 가능)
param() : API 테스트 할 떄 사용될 요청 파라미터 설정
jsonPath() : JSON 응답 값을 필드별로 검증할 수 있는 메소드, $ 기준으로 필드명 명시

 

HelloResponseDtoTest.java

package com.example.testspringboot.controller.dto;

import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;

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() : 검증하고 싶은 대상을 메소드 인자로 받음
        assertThat(dto.getAmount()).isEqualTo(amount); // isEqualTo() : 동등 비교 메소드
    }
}

 

assertThat() : 검증하고 싶은 대상을 메소드 인자로 받음
isEqualTo() : 동등 비교 메소드

 

build.gradle
plugins {
	id 'java'
	id 'org.springframework.boot' version '3.1.10'
	id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '17'
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	implementation 'org.projectlombok:lombok' // 롬복
	testImplementation 'junit:junit:4.13.1' // JUnit4
}

tasks.named('bootBuildImage') {
	builder = 'paketobuildpacks/builder-jammy-base:latest'
}

tasks.named('test') {
	useJUnitPlatform()
}
728x90