Java&Spring/Spring

Spring Test 기초[1] , assertall()

sung.hyun.1204 2022. 9. 6. 21:10

TDD 를 공부 할 때가 되었다..

단위 테스트를 어떻게 하는지 여기서는 다루지 않는다.

기본적인 어노테이션과 개념만 적어본다.

 

Junit 5 를 사용한다.

 

스프링 부트 버전 2.2+ , 프로젝트를 만든 다면 기본적으로  junit5 의존성이 추가가 된다 . 

 

JUNIT PlatForm : 테스트를 실행해주는 런처를 제공한다. testApi 제공

 

Jupiter: TestEngine API 구현체로 JUnit 5 를 제공한다.

 

Vintage : Junit 4 와 3를 지원하는 testEngine 을 지원 . 

 

test 생성 .

src folder 의 원하는 class 에 가서  , (control)cmd+shift+T 를 눌러준다. 

 

(Intellij  File -> Project Structre 에 들어가 mark as Tests  를 확인 해주자.)

 

1. Test code

@Test :  test 할 함수에 적어준다.

 

 

package com.example.testcode.domain;

import org.junit.jupiter.api.*;

import static org.junit.jupiter.api.Assertions.*;

class StudyTest {

    @Test
    void create(){
        Study study = new Study();
        assertNotNull(study);
    }

    @Test
    void create2()
    {
        System.out.println("this is create2 ");
    }

    @BeforeAll
    static  void beforecode()
    {
        System.out.println("!! before all test code !!");
    }

    @BeforeEach
    void before1()
    {
        System.out.println("before Each1");
    }

    @BeforeEach @Disabled
    void before2()
    {
        System.out.println("before Each2");
    }

    @AfterEach
    void after()
    {
        System.out.println("after each");
    }

}

@BeforeEach 의 @Disabled 는 적용이 안되는것을 확인 할 수 있다.

> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :compileTestJava
> Task :processTestResources NO-SOURCE
> Task :testClasses
> Task :test
!! before all test code !!
before Each1
before Each2
after each
before Each1
before Each2
this is create2 
after each
BUILD SUCCESSFUL in 1s
4 actionable tasks: 2 executed, 2 up-to-date
7:39:27 PM: Execution finished ':test --tests "com.example.testcode.domain.StudyTest"'.

 

 

@Test
    void create(){
        Study study = new Study();
        assertNotNull(study);
        assertEquals(StudyStatus.DRAFT,study.getStudyStatus(),"this must be draft"+StudyStatus.DRAFT+"end");
        assertEquals(StudyStatus.DRAFT,study.getStudyStatus(),()->"this must be draft"+StudyStatus.DRAFT+"end");
    }

 

❗️message 를 전부 적는것이 아닌 suppliers lambda 표현식 를 이용하자.❗️

 

왜 ? 

 

 message 를 String 으로 사용하면 test 의 성공 유무를 떠나 message 를 만드는 연산을 항상 하지만,

Suppliers 를 이용하면 test 가 실패할때만 연산을 한다 . 

 


 

Study.class

package com.example.testcode.domain;

public class Study {
    private StudyStatus studyStatus ;

    private int  limit ;

    public Study(int limit)
    {
        this.limit = limit ;
    }


    public StudyStatus getStudyStatus() {
        return this.studyStatus;
    }

    public int getLimit()
    {
        return limit ;
    }

}

 

 

StudyStatus.enum

 

package com.example.testcode.domain;


public enum StudyStatus
{
    DRAFT ,STARTED ,ENDED
}

 

assertall();

assertall 함수 안에 개별로 lambda를 넘겨 주면 , test 중 error 를 만나도 . 모든 assert 를 실행 해준다.

 

Testcode 

Stduytest

@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {

    @DisplayName("Create init")
    @Test
    void create(){
        Study study = new Study(-10);

    assertAll(
            ()->  assertNotNull(study),
            ()->assertEquals(StudyStatus.DRAFT,study.getStudyStatus(),()->"this must be draft"+StudyStatus.DRAFT+"end"),
            ()->assertTrue(study.getLimit() >0,()->"study 인원은 양수이여한다.")
        );
    }
Multiple Failures (2 failures)
	org.opentest4j.AssertionFailedError: this must be draftDRAFTend ==> expected: <DRAFT> but was: <null>
	org.opentest4j.AssertionFailedError: study 인원은 양수이여한다. ==> expected: <true> but was: <false>
Expected :true
Actual   :false
<Click to see difference>

org.gradle.internal.exceptions.DefaultMultiCauseException: Multiple Failures (2 failures)
	org.opentest4j.AssertionFailedError: this must be draftDRAFTend ==> expected: <DRAFT> but was: <null>
	org.opentest4j.AssertionFailedError: study 인원은 양수이여한다. ==> expected: <true> but was: <false>
	at app//org.junit.jupiter.api.AssertAll.assertAll(AssertAll.java:80)

 

 


throw error를 확인 하는 test 

 

생성자의  limit 에 관하여 exception 을 만들면,

package com.example.testcode.domain;

public class Study {
    private StudyStatus studyStatus ;

    private int  limit ;

    public Study(int limit)
    {
        if(limit < 0 )
        {
            throw new IllegalArgumentException("limit must be bigger than 0");
        }
        this.limit = limit ;
    }


    public StudyStatus getStudyStatus() {
        return this.studyStatus;
    }

    public int getLimit()
    {
        return limit ;
    }

}

 

1. 생성시 Error 가 호출되는지 확인 -> assertThrows

2.생성한 메세지가 같은지 확인  -> asserEquals

@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {

    @DisplayName("Create init")
    @Test
    void create(){
        IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
        ()-> new Study(-10));
        
        assertEquals("ok",e.getMessage());
    }

message 가 다른것을 알려준다.