교육과정 기록/💻back-end

[7.8] JDBC - 자원객체 이해 / JUnit 사용

춘식이왔엉 2022. 7. 8. 22:46

 

* 직접 자원객체를 만들고, try-with-resources 블록에 적용해서
과연 자원객체가 어떤 순서로 닫히는지 알아보자

 

- 먼저, 자원class 생성

이 때, AutoCloseable 인터페이스에는매개변수와 리턴타입이 없는 추상메소드가 하나 들어있음

--> functional interface 이다.

추상메소드를 오버라이딩 하자! 
--> 이유 : try-with-resources가 닫아줄 모든 자원객체(클래스)의 요건 --> AutoCloseable 해야하기 때문

@Log4j2
@NoArgsConstructor
class Resource1 implements AutoCloseable { 

	@Override
	public void close() throws Exception {
		log.trace("close() invoked.");		
	} // close
    
} // end class

 

- 자원class 2개 더 생성해서 총 3개 생성

@Log4j2
@NoArgsConstructor
class Resource1 implements AutoCloseable { 

	@Override
	public void close() throws Exception {
		log.trace("close() invoked.");		
	} // close
    
} // end class

@Log4j2
@NoArgsConstructor
class Resource2 implements AutoCloseable { 

	@Override
	public void close() throws Exception {
		log.trace("close() invoked.");		
	} // close
    
} // end class

@Log4j2
@NoArgsConstructor
class Resource2 implements AutoCloseable { 

	@Override
	public void close() throws Exception {
		log.trace("close() invoked.");		
	} // close
    
} // end class

 

- 실행블럭 작성

public class JDBCExample7 {
	
	public static void main(String args[]) {
		Resource1 res1 = new Resource1();
		Resource2 res2 = new Resource2();
		Resource3 res3 = new Resource3();
		
		try ( res1; res2; res3) {
			;;		// pass (아무것도 하지 않는다)
			
		} catch(Exception e) {
			e.printStackTrace();
		} // try-with-resources
	
	} //main

} // end class

 

- 결과창

resource3 > 2 > 1 순서로 자원 해제

 

- AutoCloseable 인터페이스를 implements 하지않으면 나타나는 에러

 


 

TDD(Test Driven Development)

- 테스트 주도 설계

- 테스트를 먼저 만들고 테스트를 통과하기 위해 코드를 짜며 실제 서비스될 코드를 작성하는 개발 방법론 중 하나이다.

- 장점 : 객체지향적인 코드 개발 가능, 설계 수정 및 디버깅 시간 단축, 유지보수 용이, 오버 엔지니어링 방지 등

- 단점 : 개발 시간 증가, 어려움

 

JUnit  

- 자바 프로그래밍 언어용 유닛 테스트 프레임워크

 

1. JUnit5 -> "JUnit Jupyter"로 이름이 바뀜
2. 사용가능한 어노테이션이 많이 증가
3. 테스트 클래스로부터, 테스트 객체를 생성하는 방법이 2가지로 바뀜
(1) PER_CLASS (테스트 객체 1개만 생성)
 (2) PER_METHOD (테스트 메소드 수행시마다, 객체 생성)

4. 테스트 메소드의 수행 순서를 결정할 수 있게됨 (@TestMethodOrder)

참고))  import org.junit.jupiter.api.TestMethodOrder; 

@Log4j2
@NoArgsConstructor

// 타입선언부 위에, 아래와 같이 기본적인 2개의 어노테이션을 설정
@TestInstance(Lifecycle.PER_CLASS)    //또는 @TestInstance(Lifecycle.PER_METHOD)
@TestMethodOrder(OrderAnnotation.class)
public class JUnit5_Template {
	// 사전처리 메소드 (@BeforeAll, @BeforeEach)는 선택
	@BeforeAll
	void beforeAll() {
		log.trace("beforeAll() invoked.");
	}
	@BeforeEach
	void beforeEach() {
		log.trace("beforeEach() invoked.");
	}
	
	@Test
	@Order(2)		// 테스트 메소드의 실행순서 지정 
	@DisplayName("덧셈 메소드의 기능을 테스트 합니다.")
	@Timeout(value=1, unit=TimeUnit.SECONDS)
	void contextLoad1() {
		log.trace("contextLoad1() invoked.");
	}
	
	@Test
	@Order(1)
	@DisplayName("곱셈 메소드의 기능을 테스트 합니다.")
	@Timeout(value=1, unit=TimeUnit.SECONDS)
	void contextLoad2() {
		log.trace("contextLoad2() invoked.");
	}
	
	// 사후처리 메소드 (@AfterAll, @AfterEach)는 선택
	@AfterEach
	void afterEach() {
		log.trace("afterEach() invoked.");
	}
	
	@AfterAll
	void afterAll() {
		log.trace("afterAll() invoked.");
	}

} //class

 

beforeAll()과 afterAll() 은 한번만 수행!! (사전/사후 처리)

Each()는 per test마다 반복된다.

< 어노테이션 설명 > 

@TestInstance(Lifecycle.PER_CLASS)  또는  @TestInstance(Lifecycle.PER_METHOD)

- 테스트 인스턴스의 생성기준을 설정

@TestMethodOrder(OrderAnnotation.class)

테스트 클래스 안에 여러개의 테스트 메소드가 있을 때,
테스트 클래스의 전체 테스트 메소드 수행시 
각 메소드의 수행순서를 @Order 어노테이션을 통해 실행순서를 지정할 때 사용함

	@Test
	@Order(2)		// 실행순서 지정
	@DisplayName("contextLoad1")
	@Timeout(value=1, unit=TimeUnit.SECONDS)
	void contextLoad1() {
		log.trace("contextLoad1() invoked.");
	}
	
	@Test
	@Order(1)
	@DisplayName("contextLoad2")
	@Timeout(value=1, unit=TimeUnit.SECONDS)
	void contextLoad2() {
		log.trace("contextLoad2() invoked.");
	}

 

결과 --> contextLoad2()가 먼저 실행됨.

 

* Class 객체를 얻어내는 방법

1. 타입명.class
2. 참조변수명.getClass()
3. Class.forName(문자열타입의 FQCN)