spring boot - 테스트

원종서·2021년 12월 27일
0

spring

목록 보기
7/12

작은 단위 테스트

자동수행 테스트 코드

기존 테스트 코드를 JUnit 테스트로 전환

JUnit 는 프레임워크다

테스트를 수행할 메소드는 JUnit 프레임워크가 요구하는 조건 두가지를 따라야한다
첫번째는 메소드가 public 이여하고,
두번째는 메소드에 @Test 어노테이션을 붙여줘야한다.

검증 코드 전환

테스트 결과를 검증하는 if/else 문장을 JUnit 이 제공하는 방법을 이용해 전환해보자

 if(!user.getName().equals(user2.getName()))import static org.hamcrest.CoreMatchers.is;
import  static org.junit.Assert.assertThat;

 assertThat(user2.getName(), is(user.getName())); 으로 바꿔준다

assertThat() 메서드는 첫 번째 파라미터 값을 뒤에 나오는 매처라고 불리우는 조건으로 비교해서 일치하면 넘어가고 아니면 테스트를 실패하고도록 만들어준다.

JUnit 테스트 실행

JUnit 프레임워크도 자바 코드로 만들어진 프로그램임으로 어디선가 한번은 Junit 프레임워크를 시작시켜줘야한다.

import org.junit.runner.JUnitCore;

 public static void main(String[] args) {
        JUnitCore.main(@TEST가 붙은 메서드를 같은 클래스이름);
    }

2.3 개발자를 위한 테스팅 프레임워크 JUnit

2.3.1 JUnit 테스트 실행 방법

  • IDE

UserDao 기능 추가하기

 @Test
    public void addAndGet() throws SQLException, ClassNotFoundException {
        ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
        UserDao dao =  context.getBean("userDao",UserDao.class);

        dao.deleteAll();
        assertThat(dao.getCount(),is(0));

        User user = new User();
        user.setId("1");
        user.setName("원종서");
        user.setPassword("hello");

        dao.add(user);
        assertThat(dao.getCount(),is(1));

        System.out.println(user.getId() + " 등록 성공");

        User user2= dao.get(user.getId());
        assertThat(user2.getName(), is(user.getName()));
        assertThat(user2.getPassword(), is(user.getPassword()));
        if(!user.getName().equals(user2.getName())){
            System.out.println("fail test (name)");
        }
        if(!user.getPassword().equals(user2.getPassword())){
            System.out.println("fail test (password)");

        }
        else{
            System.out.println("test success");
        }
    }

dao.get()메서드에 id인자를 넣었을때 해당하지 않은 아이디라면 예외를 던지도록 하겠따.
이런 테스트에는 예외를 의도적으로 발생하는 것이기 때문에 테스트에서 예외가 발생하면 테스트 성공, 발생하지 않으면 테스트 실패인 것이다.

이런 테스트를 하기 위해서는 assertThat() 메서드 말고
JUnit의 예외조건 테스트 방법을 사용해야한다.

@Test(expected = EmptyResultDataAccessException.class) 치럼
Test 애노테이션 괄호에 expected 를 쓰고 기대하는 예외 클래스를 적어주면 된다.

2.3.4 테스트가 이끄는 개발

테스트를 먼저 만들어 테스트가 실패하는 것을 보고 나서 본 코드를 수정하는 방법의 개발

기능설계를 위한 테스트

조건 : 어떤 조건을 가지고
행위ㅣ 무엇을 할떄
결과: 어떤 결과가 나온다.

테스트 주도 개발(TDD, Test Driven Development, Test Frist Development)

JUnit 프레임워크는 테스트 메소드를 실행할 때 부가적으로 해주는 작업이 몇개 있다.
그 중 테스트를 실행할 때마다 반복되는 준비 작업을 별도의 메소드에 넣게 해주고, 이를 매번 테스트 메소드를 실행하기 전에 실행시켜주는 것이 좋다.

@Before

중복된 코드를 한 머세드에 모으고 @Before 에노테이션을 붙이면

JUnit 테스트 수행 방식
1. 테스트 클래스에서 @Test가 붙고 public, void, 파라미터가 없는 테스트 메서드를 찾는다.
2. 테스트 클래스의 오브젝트를 만든다.
3. @Before 메소드를 실행한다.
4. @Test 가 붙은 메소드를 하나 호출하고 ㅌ스트 결과에 저장함.
5. @After 메소르를 실행한다.

테스트 메서드를 만들때마다 테스트 클래스의 오브젝트를 새로 만든다.

픽스처

테스트를 수행하는데 필요한 정보나 오브젝트를 픽스처라고 한다.
@Before 메서드를 이용해 픽스처를 생성하는게 편리하다.

@BeforeClass
테스트 클래스 전체에 걸쳐 딱 한번만 실행되는 스태틱 메서드를 지원한다.
이 메소드에서 애플리케이션 컨텍스트를 만들어 스태틱 변수에 저장해두고 사용할 수 있다.

2.4.1 테스트를 위한 애플리케이션

JUnit 을 이용하는 테스트 컨텍스 프레임워크를 제공한다.
테스트 컨텍스트의 지원을 받으면서 간단한 애노테이션 설정만으로 테스트에서 필요로하는 앱 컨텍스트를 만들어 모든 테스트가 공유할 수 있게 할 수 있다.

위를 적용하기 위해 아래의 코드를 쓴다,

@RunWith(SpringJUnit4ClassRunner.class) // 스프링 테스트 컨텍스트 프레임워크의 JUnit 확장기능 지정
@ContextConfiguration(locations = "/applicationContext.xml") // 텍스트 컨테스트가 자동으로 만들어줄 앱 컨텍스트의 위치
public class UserDaoTest2 {
    @Autowired
    ApplicationContext context ;// 테스트 오브젝트가 만들어지고 나면 스프링 테스트 컨텍스트에 의해 자동으로 값이 주입된다.	

SpringJUnit4ClassRunner라는 JUnit용 테스트 컨텍스트 프레임워크 확장 클래스를 지정해주면 JUnit이 테스트를 진행하는 중에 테스트를 사용할 앱 컨텍스트를 만들고 관리해준다.

위처럼 테스트 컨텍스트를 사용하면 같은 클래스의 메소드 뿐 아니라, 설정 파일이 같은 다른 클래스에서도 같은 텍스틐 컨텍스트를 사용한다

@Autowired (자동와이러닝)

스프링의 Di에 사용되는 특별한 애노테이션
@Autowired이 붙은 인스턴스 변수가 있으면, 테스트 컨텍스트 프레임워크는 변수 타입과 일치하는 컨텍스트 내의 빈을 찾는다.
타입이 일치하는 빈이 있으면 주입시켜준다.

스프링 앱 컨텍스트는 초기화할때 자기 자신 빈으로 등록된다. 따라서 앱 컨텍스트에는 ApplicationContext 타입의 빈이 존재하는 셈이고 Di된 것이다.

getBean("userDao",UserDao.class) ->
->
@Autowired
UserDao dao;

를 하는것이 앱 컨텍스트를 Di 받아서 다시 DL 방식으로 Dao을 가져올때보다 깔끔하다

단 같은 타입의 빈이 두개 있는 경우에는 어떤 빈을 가져와야할지 결정할 수 없다
그러면 변수 이름과 같은 이름의 빈이 있는지를 찾고, 같은 이름의 빈을 주입시킨다.

2.4.2 DI와 테스트

XMl에 정의한 설정 파일말고 테스트에서 다른 설정파일, 인터페이스를 구현한 다른 클래스를 이용하고 싶을때는

@DirtiesContext
public class TEst{
	@AutoWired
    UserDao dao;
    
	DataSource datasource = new SingleConnectionDataSource(...);
    dao.setDataSource(datasource)

위처럼 수동으로 생성해서 DI 해줄 수 있다.

하지만 주의해야한다. 이미 앱 컨텍스트에서는 XML 파일의 설정 정보를 따라 구성한 오브젝트를 가져와 의존관계를 강제로 변경했기 때문.

딱 한개로 같은 설정파일을 공유하는 앱 컨텍스트에 위같은 설정 정보 변경은 치명적이다.

그러므로 클래스명 위에 @DirtiesContext 를 붙여 스프링의 테스트 컨텍스트 프레임워크에게 해당 클래스의 테스트에서 앱 컨텍스트의 상태를 변경한다는 것을 알려준다, 이 어노테이션으로 앱 컨텍스트 공유를 하지 않는다. 테스트가 반복 될때마다 새로운 앱 컨텍스트를 만든다.

다른 방법으로는 새로운 설정 파일 XML을 만드는 것이다. 이 방법이 좋다

학습테스트

JUnit 테스트 오브젝트 테스트

JUnit 에 대한 학습 테스트, JUnit으로 만드는 JUnit자신에ㅡ대한 테스트다

0개의 댓글