Back-End/스프링부트와 AWS로 구현하는 웹서비스

[스프링][Spring] 2. 테스트 코드 작성하기

얄루몬 2022. 1. 10. 04:02

👽본격적으로 챕터에 들어가기 앞서서 앞의 문제를 해결했다 그래서 스프링부트 연결까지 성공했다.

 

참고로 이 책은 JUnit4를 쓴다. 현재 JUnit을 많이 사용해서 문법이 달라지는 부분이 많아서https://jojoldu.tistory.com/539?category=717427 에 방문하여 확인해주시길 바란다.

책으로 공부하게 되면 이런 문제가 생긴다.
버전이 서로 호환이 안 된다거나 그런 문제 ㅋ...

그래서 이번엔 책의 저자 티스토리에 가서 가장 최근에 bulid.gradle 수정한 부분을 찾아서 적용해주니 아주 잘 돌아갔다. 
plugins { // (1)
    id 'org.springframework.boot' version '2.4.1' // RELEASE 삭제
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
    id 'java'
}

group 'com.jojoldu.book'
version '1.0.4-SNAPSHOT-'+new Date().format("yyyyMMddHHmmss")
sourceCompatibility = 1.8

repositories {
    mavenCentral()
    jcenter()
}

// for Junit 5
test { // (2)
    useJUnitPlatform()
}

dependencies {
    //(3)
    implementation('org.springframework.boot:spring-boot-starter-web')
    implementation('org.springframework.boot:spring-boot-starter-mustache')

    // lombok
    implementation('org.projectlombok:lombok')
    annotationProcessor('org.projectlombok:lombok')
    testImplementation('org.projectlombok:lombok')
    testAnnotationProcessor('org.projectlombok:lombok')

    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
    implementation("org.mariadb.jdbc:mariadb-java-client")
    implementation('com.h2database:h2')


    testImplementation('org.springframework.boot:spring-boot-starter-test')
}​

 


 

1. 테스트 코드에 앞서 메인 클래스 작성하기 

package com.yeomyaloo.book.springboot;

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

import static org.springframework.boot.SpringApplication.run;
import static org.springframework.boot.autoconfigure.SpringBootApplication.*;



// Annotation이라고 부르며 스프링 부트의 자동 설정, 스프링 Bean 읽기와 생성을 모두 자동으로 설정해준다.
// 특히 @SpringBootApplication 아래부터 설정이 되기 때문에 꼭 최상단에 위치해야 한다. 
@SpringBootApplication
    public class Application{
        public static void main(String[] args){
        
            // 아래로 인해서 내장 WAS(웹 애플리케이션 서버)를 실행한다. 
            SpringApplication.run(Application.class,args);
        }
    }

테스트 코드 작성을 하고 테스트 하기 위해서 메인 클래스를 만드는 작업을 진행한다.

 

정리 

  • @SpringBootApplication
    • Annotation이라고 부르며 스프링 부트의 자동 설정, 스프링 Bean 읽기와 생성을 모두 자동으로 설정해준다.
  • WAS (web Application server, 웹 애플리케이션 서버) - 별도로 외부에 WAS를 두지 않고 애플리케이션을 실행할 때 내부에서 WAS를 실행하는 것을 이야기 한다. 이렇게 하면 항상 서버에 톰캣을 설치할 필요가 없고 스프링 부트로 만들어진 Jar  파일로 실행하면 된다.
  • 스프링부트에서 WAS 사용을 권장하는 이유는 '언제 어디서나 같은 환경에서 스프링 부트를 배포'할 수 있기 때문이다. 여러 외부 WAS를 사용하면 그때마다 새로 설치해야 해서 매우 번거롭기 때문에 내부 WAS를 쓰는 것을 권고한다. 

 

 

위의 메인 페이지 작성 후 실행하게 되면 이렇게 스프링에 연결되었다는 메시지가 나온다 볼때마다 나름 귀여움 ㅋ

 

 

2. [JUnit] intellij 에서 junit 테스트 코드 작성 시 경험 하는 에러.

(Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.)

 

👇참고하세요!!

 

[JUnit] intellij 에서 junit 테스트 코드 작성 시 경험 하는 에러.

아래와 같은 에러를 경험 하셨다면 intellij 에서의 설정을 변경해 주시면 됩니다. Execution failed for task ':test'. > No tests found for given includes: [com.kakaopay.stark.pipeline.indexer.PropertiesT..

jjeong.tistory.com

default 값을 gradle에서 intellij로 바꿔주면 되는 문제였는데 다들 인텔리제이로 바꿔 쓰는게 훨씬 빠르다고 해서 원래 그렇게 하고 쓰긴 했었다 JUnit오류가 날 줄이야.. 

 

3. 테스트 코드 작성하기

package com.yeomyaloo.book.springboot;

import com.yeomyaloo.book.springboot.web.HelloController;
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 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 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 사이에 연결자 역할을 한다!
  • 테스트 코드는 System.out.println();을 사용해서 진행하지 않는다 현업에서 역시 마찬가지.

성공적으로 됐다면 프로젝트 실행 시에 저런 화면이 뜨게 된다.

 

4. 롬복

롬복이란?

  • 자바 개발자들의 필수 라이브러리이다.
  • 자바 개발할 때 자주 사용하는 코드 Getter / Setter / 기본 생성자 / toString등을 어노테이션으로 자동 생성해준다.
  • 이클립스에선 롬복 설치가 번거롭지만, 인텔리제이에선 플러그인 덕분에 쉽게 설정이 가능하다.

  • 참고로 Gradle 버전에 따라서 다른데 책에서는 compile이라 나와있지만 현재는 아마도 implemetation을 써야 하는 것으로 안다. 
  • 위와같은 작업을 라이브러리를 내려받는다. (혹은 의존성이라고 한다.)

 

 

Gradle5 -> 6 마이그레이션

최근 팀에서 운영중인 프로젝트의 Gradle 버전을 6으로 올리게 되었습니다. 사유는 여러가지가 있는데요. 점점 Spring Boot 최신 버전들이 최소한으로 요구하는 Gradle 버전이 높아지고 있고 Spring Boot 2

jojoldu.tistory.com

이와 관련된 자료는 이곳에서 살펴보도록 하자

 

<롬복 설치 시>

이미 롬복을 설치해놨을 수도 있다. 그러면 마켓플레이스 옆에 설치됨을 보도록 하자 

설치되어 있다면 롬복을 사용해서 설정하는 방법을 위의 캡쳐를 따라 설정해둔 뒤 롬복으로 리팩토링을 진행해보자

 

5. Hello Controller 코드를 롬복으로 전환하기

 

대규모의 프로젝트라면 롬복 전환이 쉬울까? 쉽지 않을 것이기 떄문에 테스트 코드를 사용해서 이를 확인하고 사용해야 한다. 

--> 딱히 설정이 되지 않아서 시간 지체 없이 get / set  alt + insert 사용해서 진행하기로 했다.

package com.yeomyaloo.book.springboot.dto;

import com.yeomyaloo.book.springboot.web.HelloController;
import com.yeomyaloo.book.springboot.web.dto.HelloResponseDto;
import org.junit.Test;
import lombok.Getter;

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);

    }
}
package com.yeomyaloo.book.springboot.web.dto;

import lombok.RequiredArgsConstructor;


@RequiredArgsConstructor
public class HelloResponseDto {

    private final String name;
    private final int amount;

    public String getName() {
        return name;
    }

    public int getAmount() {
        return amount;
    }
}