테스트2

트곰·2022년 4월 16일
0

토비스프링

목록 보기
3/3

스프링 테스트 적용

빈이 많아지고 복잡해지면 ApplicationContext 생성에 적지 않은 시간이 걸릴 수 있다. ApplicationContext가 만들어질 때 모든 싱글톤 빈 오브젝트를 초기화하는데, 이 작업이 많은 시간이 소요된다.
이 문제를 해결하기 위해서 ApplicationContext를 static 레벨에 저장해두는 방법도 있지만, 스프링이 직접 제공하는 ApplicationContext 테스트 지원 기능을 사용하는 것이 편리하다.

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

스프링 테스트 컨텍스트 프레임워크 적용

@Runwith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="/applicationContext.xml")
public class UserDaoTest {
	@Autowired
    private ApplicationContext context;
    
    @Before
    public void setUp() {
    	this.dao = this.context.getBean("userDao", UserDao.class);
    }
}

context를 초기화해주는 코드는 없어서, 메소드에서 context를 사용하려면 NullPointerException이 발생하지만, 테스트에서는 아무런 문제가 발생하지 않는다.

여기서 더 간단하게는, UserDao를 주입받아서 사용할 수도 있다.

public class UserDaoTest {
	@Autowired
    UserDao dao;
}

DI와 테스트

DataSource의 구현 클래스를 바꾸지 않고, DB 커넥션의 정보를 바꾸 일이 없는데도, 굳이 인터페이스를 사용해서 DI를 주입해주는 방식을 사용해야 할까?
(매일 고민하는 부분...)

  1. 소프트웨어 개발에서 절대로 바뀌지 않는 것은 없기 때문에, 클래스 대신 인터페이스를 사용하고 new를 이용해서 생성하는 대신 DI를 통해 주입받게 하는 것은 아주 단순하고 쉬운 작업이다. 당장에는 클래스를 바꿔서 사용할 계획이 없더라도 언젠가 변경이 필요한 상황이 닥친다면 수정에 들어가는 시간, 비용을 줄일 수 있다.
  2. 클래스의 구현 방식은 바뀌지 않더라도 인터페이스를 두고 DI를 적용해두면 다른 차원의 서비스 기능을 도입할 수 있기 때문이다. 스프링의 AOP 기법을 적용하기 위해선 기본적으로 DI 적용이 필요하다.
  3. 효율적인 테스트를 손쉽게 만들기 위해서라도 DI를 적용해야 한다.
    DI는 테스트가 작은 단위의 대상에 대해 독립적으로 만들어지고 실행되기 하는데 중요한 역할을 한다.
테스트 코드에 의한 DI

테스트를 하면서 실제 운영되는 DB에 사용자 정보를 수정하거나 삭제하는 일이 벌어진다면???
그러지 않으려면, @DirtiesContext로 ApplicationContext 구성이나 상태를 변경한다는 것을 알리고, DataSource의 정보를 다시 생성해서 사용하는 방법이 있다. 하지만, 이미 주입받은 것을 다시 덮어쓰기?하는 느낌으로
별도의 DI를 설정하는 방법이 있다.

테스트를 위한 별도의 DI 설정

책에서는 xml 파일을 별도로 두고, @ContextConfiguration으로 설정 파일의 정보를 알려주는 방식을 알려주고 있지만, 나는 properties 파일을 적용하고 있어서 찾아보았다.

https://stackoverflow.com/questions/32974432/spring-junit-testing-properties-file

배포용과 로컬 DB 정보를 별도로 두고, 설정해줬던 방법처럼
application-test.properties 파일을 만들고 경로 지정하려고 하며 검색해보니, 스택오버플로우에 좋은 답변이 있다.

test에서는 굳이 파일명을 다르게 할 필요가 없이, 경로를 main, test 위치만 다르게 하여서 @PropertySource("classpath:application.properties ")로 경로를 알려주는 방법이 있었다.

컨테이너 없는 DI 테스트
public class UserDaoTest {
	UserDao dao;
    
    @Before
    public void setUp() {
    	dao = new UserDao();
        DataSource dataSource = new SingleConnectionDataSource("jdbc:mysql://localhost/testdb", "spring", "book", true);
        dao.setDataSource(dataSource);
    }
    
}

@Autowired를 하지 않아도 되고, 직접 오브젝트 생성, 관계 설정을 해준다.
Autowired는 하나만 주입 시에는 생략해도, 필드 주입이 가능하고,,,
@Before 어노테이션으로 무조건 해당 메소드가 실행되니까 메소드 내부에서 생성을 해주는 방법이 가능한 것 같다.


학습 테스트

학습 테스트의 장점

  1. 다양한 조건에 따른 기능을 손쉽게 확인해볼 수 있다.
  2. 학습 테스트 코드를 개발 중에 참고할 수 있다
  3. 프레임워크나 제품을 업그레이드할 때 호환성 검증을 도와준다.
  4. 테스트 작성에 대한 좋은 훈련이 된다.
  5. 새로운 기술을 공부하는 과정이 즐거워진다.ㅎㅎㅎㅎ
profile
개발자가 되기 위해서 공부중입니다 :ㅡ)

0개의 댓글