토비의 스프링 1권 2장 - 테스트

2024.09.29 (SUN)


스프링이 개발자에게 제공하는 가장 중요한 가치

  • 객체지향
  • 테스트

스프링은 IoC/DI를 이용해 객체지향 프로그래밍 언어의 근본과 가치를 개발자가 손쉽게 적용하고 사용할 수 있게 도와주는 기술이다.

애플리케이션은 점점 복잡해져 가는데, 그렇게 만들어진 코드를 확신할 수 있게 해주고, 변화에 유연하게 대처할 수 있는 자신감을 주는 것이 테스트 기술이다. +) 또한 테스트는 스프링을 학습하는 데 있어 가장 효과적인 방법 중 하나!

테스트는 가능한 작게

  • 작은 단위의 테스트 (단위 테스트 / unit test)
    • 테스트를 한꺼번에 너무 몰아서 많은 것을 하면, 테스트 수행 과정도 복잡해진다.

테스트의 효율 향상을 위한 방법

  1. 테스트 검증의 자동화
  • 수정 전
    System.out.prinln(user2.getName());
    System.out.prinln(user2.getPassWord());
    System.out.prinln(user2.getId() + " 조회 성공");
    
  • 수정 후 (자동화)
    if (!user.getName().equals(user2.getName())) {
      System.out.println("테스트 실패 (name)");
      // ...
    }
    

개발자의 눈으로 일일히 확인할 필요 없이, 테스트를 실패하였는지 성공하였는지를 확인한다.

  1. 테스트의 효율적인 수행과 결과 관리
    • JUnit을 활용한 단위 테스트
    • 테스트의 수가 많아지면, IDE에 내장된 JUnit 테스트 지원 도구를 사용하는 것도 좋다.
      • ex). 이클립스 (run -> Run As -> JUnit Test)
    • “항상 네거티브 테스트를 먼저 만들라”
      • 개발자는 흔히 “내가 할 떄는 잘됐는데”가 내장되어있을 수 있다..
    • TDD : 테스트 주도 개발
      • 개발자가 테스트를 만들어가며 개발하는 방법이 주는 장점을 극대화한 방법
      • “실패한 테스트를 성공시키기 위한 목적이 아닌 코드는 만들지 않는다.”

JUnit 활용

@Before

  • 매번 테스트마다 중복된 메소드를 불러온다면, @Before 애노테이션으로 설정해준다면, 각 테스트 메소드에서 코드를 실행하기 전에 @Before을 먼저 실행시킨다.
public class UserDaoTest {
	private UserDao dao;

	@Before
	public void setUp() {
		ApplicationContext context = 
			new GenericXmlApplicationContext("applicationContext.xml");
		this.dao = context.getBean("userDao", UserDao.class);
	}

	@Test
	public void addAndGet() throws SQLException {
		// 각 테스트 메소드에 반복적으로 나타났던 코드를 제거하고 이를 @Before 에 옯겨 놓는다.
		// ...
	}

	@Test
	public void count() throws SQLException {
		// 각 테스트 메소드에 반복적으로 나타났던 코드를 제거하고 이를 @Before 에 옯겨 놓는다.
		// ...
	}

	// ...
	
}
  • JUnit이 제공하는 @Before 애노테이션, @Test 메소드가 실행되기 전에 먼저 실행되어야 하는 메소드를 정의한다.

테스트를 위한 애플리케이션 컨텍스트 관리

  • 애플리케이션 컨텍스트를 매 테스트마다 생성하는 것은 불필요하기 때문에, 스태틱 변수에 저장하는 등의 방법이 필요하다.
    • 그런 방법들 보다는 스프링이 직접 제공하는 애플리케이션 컨텍스트 테스트 지원 기능을 이용하는 것이 더 편리하다. (@RunWith, @ContextConfiguration)
    • 매 테스트 메소드가 실행되기 전에 한번씩 실행되며, 모두 새로운 테스트 오브젝트를 만들어 사용한다. (애플리케이션 컨텍스트 재사용)
    • 여러 개의 테스트 클래스에게도 공유 가능

@Autowired

  • 스프링 DI에 사용되는 특별한 애노테이션
  • @Autowired가 붙은 인스턴스 변수가 있으면, 테스트 컨텍스트 프레임워크는 변수 타입과 일치하는 컨텍스트 내 빈을 찾는다.
    • 타입이 일치하는 빈이 있으면 인스턴스 변수에 주입해준다.
    • 일반적으로 주입을 위해서는 생성자나 수정자 메소드 같은 메소드가 필요하지만, 이 경우에는 메소드가 없어도 주입이 가능
    • ‼️‼️ 단, 같은 타입의 빈이 두 개 이상 있는 경우는 타입만으로 결정할 수 없다.
      • 선택할 수 없는 경우에는, 변수의 이름과 같은 이름의 빈이 있는지 확인
        • 이름으로도 찾을 수 없으면, 예외 발생
  • 이를 통해서, 자신이 사용하는 오브젝트의 클래스가 무엇인지 알 필요가 없다는 장점이 있다.

학습 테스트

  • JUnit 자신에 대한 테스트를 통해, 테스트를 학습 테스트로 사용해 볼 수 있다.

2장 요약

  • 테스트는 자동화되어야 하며, 빠르게 실행되어야 한다.
  • main() 테스트 대신 JUnit 프레임워크를 이용한 테스트 작성이 편리하다.
  • 테스트하기 쉬운 코드가 좋은 코드다.