티스토리 뷰

728x90
반응형

이번 시간에는 Spring Boot JUnit 활용 및 Spring Boot Property 호출 과정에 대해 살펴보겠습니다.

지난 시간에 Hello World를 출력해 보았고 어떠한 Work Flow를 기준으로 호출되는지 알아보았습니다.

이를 기반으로 작성하게 될 클래스에서는 JUnit Test 및 Spring 설정 파일에 적용한 Property를 호출하는 과정에 대해 살펴보겠습니다.

 

SpringBootTest Class 작성

먼저 아래와 같이 SpringBootTest Class를 작성합니다.

상세한 소스에 대한 내용은 하단에서 살펴보도록 하겠습니다.

1) application.yml 작성

server:
  port: 8000
propertyTest: test
propertyTestList: 1,2,3
property:
  test:
      value: property call test

propertyTest - 단일 변수

propertyTestList - 배열 변수

property.test.value - Depth가 있는 변수

 

2) SpringBootStartTest.java 작성

package com.nrson.spring.boot.simpleservice;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootStartTest {
	@Value("${noKey:default test Value}")
	private String defaultValue;
	
	@Value("${propertyTest}")
	private String propertyTest;
	
	@Value("${propertyTestList}")
	private String[] propertyTestArray;

	@Value("#{'${propertyTestList}'.split(',')}")
	private List<String> propertyTestList;
	
	@Value("${property.test.value}")
	private String propertyTestValue;

	/**
	 * @author nrson
	 * @Date 2019.07.14 04:17
	 * @return null
	 * 
	 * Value matches application.yml properties Value annotation take single
	 * value Compare Success or Fail Test by junit
	 */
	@Test
	public void testValue() {
		assertThat(defaultValue, is("default test Value"));
		
		assertThat(propertyTest, is("test"));

		assertThat(propertyTestArray[0], is("1"));
		assertThat(propertyTestArray[1], is("2"));
		assertThat(propertyTestArray[2], is("3"));

		assertThat(propertyTestList.get(0), is("1"));
		assertThat(propertyTestList.get(1), is("2"));
		assertThat(propertyTestList.get(2), is("3"));
		
		assertThat(propertyTestValue, is("property call test"));
	}
}

본 클래스에서 테스트 하고자 하는 부분은 바로 application.yml에 정의된 프로퍼티를 Spring Boot 클래스에서 어떻게 호출하고 적용할 수 있는지 입니다.

테스트를 위해 역시나 여러 어노테이션이 사용되었고 이에 대한 설명은 하단에서 설명하도록 하겠습니다.

요점만 말하자면, application.yml에 정의 된 Property를 불러와 비교한 후 맞으면 Success, 다르면 Fail을 발생 시키도록 구현한 JUnit Test 과정입니다.

JUnit Test

1) 호출 결과

호출 결과는 다음과 같습니다.

실행하면 왼쪽 상단의 JUnit Test 결과를 확인할 수 있습니다.

정상적으로 Error 없이 호출 된 것을 확인할 수 있습니다.

Error를 강제로 발생 시켜 보기 위해 Property 값 중 assertThat(defaultValue, is("default test Value")); 값을 assertThat(defaultValue, is("default Error Value"));로 변경하고 호출해 보도록 하겠습니다.

다음과 같이 Failures Count가 하나 올라갔으며, Failure Stack Trace를 확인해 보면

Expected: is "default Error Value"

but: was "default test Value"

라는 실패 원인에 대해 확인할 수 있습니다.

결과적으로 application.yml에 설정한 프로퍼티를 정상적으로 불러오고 있다고 판단할 수 있겠습니다.

 

2) 소스 확인

이번 SpringBootStartTest 클래스에서도 새롭게 사용된 어노테이션을 기준으로 살펴보도록 하겠습니다.

a) @RunWith(SpringRunner.class)

@RunWith 어노테이션을 사용하면 JUnit에 내장된 자체 Runner.class를 사용하는 대신 정의된 Runner를 사용할 수 있습니다. SpringBootTest를 수행하기 위해서는 SpringRunner.class를 정의하여 사용해야 합니다.

b) @SpringBootTest

@SpringBootTest 어노테이션은 스프링 부트 애플리케이션 테스트 시 테스트에 필요한 모든 의존성을 제공하는 어노테이션입니다. Test를 Embedded Servlet Container를 사용하여 진행할지 또는 Mockup으로 테스트를 진행할지 결정할 수 있습니다.

앞서 별도의 지정없이 테스트할 경우 Embedded Tomcat으로 호출되는 것을 확인하였습니다. 이번에는 Mockup Test를 진행해 보도록 하겠습니다.

Sample은 간단히 작성하도록 하겠습니다.

먼저 Service Class입니다.

- SpringBootSampleService

package com.nrson.spring.boot.simpleservice;

import org.springframework.stereotype.Service;

@Service
public class SpringBootSampleService {

    public String getName(){
        return "Hello";
    }
}

- SpringBootStartMockTest

package com.nrson.spring.boot.simpleservice;

import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootStartMockTest {
	@MockBean
	SpringBootSampleService springBootSampleService;

	@Test
	public void testValue() throws Exception {
		when(springBootSampleService.getName()).thenReturn("Hi");
		System.out.println(springBootSampleService.getName());
		assertTrue("Hi".equals(springBootSampleService.getName()));
		assertTrue("Hello".equals(springBootSampleService.getName()));
	}
}

위와 같이 Service Class와 Mockup Test를 수행할 Test Class를 작성하고 수행하면 다음과 같은 결과를 얻을 수 있습니다.

먼저 Mockup Test는 마이크로서비스 또는 분산 환경으로 구성된 애플리케이션을 미리 정의한 규격에 맞게 사전 정의한 리턴 값으로 테스트를 수행하는 방식을 의미합니다.

@MockBean어노테이션은 Mock Test를 위한 Service 클래스를 정의하며, 이는 어노테이션 없이

import static org.mockito.Mockito.mock;

...

SpringBootSampleService springBootSampleService = mock(SpringBootSampleService.class);

으로 정의할 수 있습니다.

Mock Test 과정을 하나하나 살펴보자면,

- when(springBootSampleService.getName()).thenReturn("Hi");

SpringBootSampleService.getName()의 return을 Hi로 받을 것이라 가정하고 지정합니다. 이는 실제 SpringBootSampleService.getName()의 리턴인 Hello 값과는 상관없이 임의로 리턴을 지정할 수 있습니다.

- System.out.println(springBootSampleService.getName());

실제로 stdout으로 출력해 보면 Hello가 아닌 Hi로 출력되는 것을 확인할 수 있습니다.

- assertTrue("Hi".equals(springBootSampleService.getName()));

assertTrue를 사용해 JUnit에 테스트 결과를 리턴합니다. 이는 실제 SpringBootSampleService의 결과와 상관없이 앞서 지정한 Hi와 비교를 수행하여 Success가 리턴됩니다.

- assertTrue("Hello".equals(springBootSampleService.getName()));

assertTrue를 사용해 JUnit에 테스트 결과를 리턴합니다. 이는 실제 SpringBootSampleService의 결과와 상관없이 앞서 지정한 Hi와 비교를 수행하여 Failures가 리턴됩니다.

이와 같이 Mockup Test를 통해 비즈니스 로직이 구현되기 전의 서비스를 사전에 테스트 할 수 있도록 마이크로 서비스 개발에 최적화 된 테스트 방식을 사용할 수 있습니다.

c) @Value

@Value 어노테이션은 application.yml에 지정한 프로퍼티를 호출할 수 있도록 하는 어노테이션입니다. 이미 1) 호출 결과에서 확인했듯이 yaml 파일에서 프로퍼티를 호출하여 매칭 시키는 역할을 수행합니다.

d) @Test

@Test 어노테이션은 main method와 비슷한 역할이라 볼 수 있습니다. JUnit을 실행하는 클래스에서 @Test 어노테이션이 지정된 메소드는 테스트를 수행하는 메소드로 지정됩니다. JUnit은 각각의 테스트가 서로 영향을 주지 않고 독립적으로 실행되는 것을 원칙으로 하여 @Test 어노테이션 마다 별도의 객체를 생성하고 테스트합니다.

 

이번 시간에는 Spring Boot를 활용한 JUnit Test 방법 중 @RunWith(SpringRunner.class) & @SpringBootTest 어노테이션을 활용한 embedded Servlet Container를 활용하는 방법과 Mockup Test 방법에 대해 살펴보았습니다.

또한 @Value 어노테이션을 활용하여 application.yml 파일에 지정된 프로퍼티 호출 방법까지 살펴보았습니다.

앞서 살펴본 SpringBootTest + Mockup Test를 기반으로 마이크로서비스 아키텍처 설계에 도움이 되기 바랍니다.

 

# 참조

-Dspring.profiles.active 옵션의 annotation => @ActiveProfiles("local")

728x90
반응형