이 section에서는 Spring Boot에 대해 자세히 설명합니다. 여기에서 사용하고 customize 할 수 있는 주요 기능에 대해 알아볼 수 있습니다. 아직 시작하지 않은 경우 "getting-started.html" 및 "using-spring-boot.html" section을 통해 기본 지식을 잘 이해할 수 있습니다.
1. Logging
Spring Boot는 모든 내부 logging에 Commons Logging을 사용하지만 기본 로그 구현은 오픈되어 있습니다 Java Util Logging, Log4J2, and Logback에 대한 기본 구성이 제공됩니다.. 각각의 경우에 logger는 optional file output도 사용 가능한 console output을 사용하도록 사전 구성되어 있습니다.
기본적으로 "`Starters`"를 사용하면 Logback이 logging에 사용됩니다. Java Util Logging, Commons Logging, Log4J 또는 SLF4J를 사용하는 종속 library가 모두 올바르게 작동하는지 확인하기 위해 적절한 logback routing도 포함됩니다.
Java에 사용할 수 있는 logging framework가 많이 있습니다. 위 목록이 헷갈리더라도 걱정하지 마세요. 일반적으로 logging dependencies을 변경할 필요가 없으며 Spring Boot 기본값이 잘 작동합니다. |
application을 servlet container 또는 application server에 배포할 때 Java Util Logging API를 통해 수행된 logging은 application의 log로 route 되지 않습니다. 이렇게 하면 container 또는 container에 배포된 다른 application에서 수행한 logging이 application의 log에 표시되지 않습니다. |
1.1. Log Format
Spring Boot의 default log output은 다음 예제와 유사합니다:
2019-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52 2019-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2019-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms 2019-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 2019-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
다음 항목이 출력됩니다:
-
Date and Time: Millisecond의 정밀도와 쉽게 정렬 가능.
-
Log Level:
ERROR
,WARN
,INFO
,DEBUG
, orTRACE
. -
Process ID.
-
실제 log message의 시작을 구분하는
---
구분자. -
Thread name: 대괄호로 묶여 있습니다. (console output을 위해 잘릴 수 있음)
-
Logger name: 일반적으로 source class name. (종종 축약됨)
-
The log message.
Logback은 FATAL level을 가지고 있지 않습니다.
이는 ERROR 로 맵핑됩니다.
|
1.2. Console Output
default log configuration은 작성될 때 console에 message를 표시합니다.
default로 ERROR
-level, WARN
-level, 그리고 INFO
-level message가 기록됩니다.
by starting your application with a --debug
flag로 application을 시작하여 “debug” mode 를 활성화할 수도 있습니다.
$ java -jar myapp.jar --debug
application.properties 에서 debug=true 를 지정할 수도 있습니다.
|
debug mode가 활성화되면 더 많은 정보를 출력하도록 core logger (embedded container, Hibernate 및 Spring Boot) 선택이 구성됩니다.
debug mode를 활성화해도 DEBUG
level로 모든 message를 기록하도록 application이 구성되지는 않습니다.
또는 --trace
flag (또는 trace=true
in your application.properties
) 로 application을 시작하여 “trace” mode를 활성화할 수 있습니다.
이렇게 하면 선택한 core logger (embedded container, Hibernate schema generation 및 전체 Spring Boot portfolio)에 대한 trace logging이 가능합니다.
1.2.1. Color-coded Output
termintal이 ANSI를 지원하는 경우 가독성을 높이기 위해 색상 출력이 사용됩니다.
spring.output.ansi.enabled
를 supported value 으로 설정하여 auto-detection을 override 할 수 있습니다..
색 구분은 %clr
conversion word를 사용하여 구성됩니다.
가장 간단한 형식으로 converter는 다음 예와 같이 log level에 따라 출력에 색상을 지정합니다.:
%clr(%5p)
아래 table은 색상에 대한 log level mapping을 설명합니다.:
Level | Color |
---|---|
|
Red |
|
Red |
|
Yellow |
|
Green |
|
Green |
|
Green |
또는 변환 옵션을 제공하여 사용해야 하는 색상 또는 스타일을 지정할 수 있습니다. 예를 들어 text를 노란색으로 만들려면 다음 설정을 사용합니다:
%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}
The following colors and styles are supported:
-
blue
-
cyan
-
faint
-
green
-
magenta
-
red
-
yellow
1.3. File Output
기본적으로 Spring Boot log는 console 만 log를 처리하고 log file을 작성하지 않습니다.
만약 console 출력 외에 log file을 남기길 원한다면 configprop:logging.file.name[] 또는 configprop:logging.file.path[] property를 (예를 들면 application.properties
에서) 설정해야 합니다.
아래 테이블은 logging.*
properties를 함께 사용할 수 있는 방법을 보여줍니다.:
configprop:logging.file.name[] | configprop:logging.file.path[] | Example | Description |
---|---|---|---|
(none) |
(none) |
Console only logging. |
|
Specific file |
(none) |
|
지정된 log file에 기록합니다. 이름은 정확한 위치이거나 또는 현재 directory에 상대적일 수 있습니다. |
(none) |
Specific directory |
|
지정된 directory에 |
Log file은 10MB에 도달하면 rotate 되며 console output과 마찬가지로 ERROR
-level, WARN
-level 및 INFO
-level message가 default로 기록됩니다.
Logging properties는 실제 logging infrastructure에 독립적입니다.
결과적으로 특정 configuration key들은(logback을 위한 logback.configurationFile 같은) Spring Boot에서 관리되지 않습니다.
|
1.4. File Rotation
만약 logback을 사용하는 경우 application.properties
또는 application.yaml
file에서 log rotation setting을 자세하게 할 수 있습니다.
다른 모든 logging system의 경우 직접 rotation setting을 구성해야 합니다. (예를 들면 Log4j2를 사용하는 경우 log4j.xml
file을 추가하여 사용)
다음 rotation policy properties가 지원됩니다.:
Name | Description |
---|---|
configprop:logging.logback.rollingpolicy.file-name-pattern[] |
log archive를 만드는데 사용되는 filename pattern입니다. |
configprop:logging.logback.rollingpolicy.clean-history-on-start[] |
application이 시작될 때 log archive cleanup이 수행되어야 하는 경우 |
configprop:logging.logback.rollingpolicy.max-file-size[] |
archive 되기 전 log file의 maximum size |
configprop:logging.logback.rollingpolicy.total-size-cap[] |
log archive를 삭제할 수 있는 maximum amount |
configprop:logging.logback.rollingpolicy.max-history[] |
log archive 보관 일 수 (default : 7) |
1.5. Log Levels
모든 지원되는 logging system은 TRACE, DEBUG, INFO, WARN, ERROR, FATAL 또는 OFF 중 하나를 level
로 logging.level.<logger-name>=<level>
을 사용하여 logger level을 Spring Environment
에 (예를 들면 application.properties
에) 설정할 수 있습니다.
logging.level.root
를 사용하여 root
logger를 설정할 수 있습니다.
아래 예제는 application.properties
의 잠재적 logging 설정을 보여줍니다:
logging.level.root=warn
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error
logging:
level:
root: "warn"
org.springframework.web: "debug"
org.hibernate: "error"
environment variable을 사용하여 logging level을 설정할 수도 있습니다.
예를 들어 LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG
는 org.springframework.web
을 DEBUG
로 설정합니다.
위의 접근 방식은 package level logging에 대해서만 적용됩니다.
relaxed binding은 언제나 environment variable을 소문자로 변환하기 때문이 이 방식으로 개별 class에 대한 logging을 설정할 수 없습니다.
만약 class에 대해 loggin을 설정하고자 하는 경우 the SPRING_APPLICATION_JSON variable을 사용할 수 있습니다.
|
1.6. Log Groups
관련 logger를 함께 그룹화하여 모두 동시에 구성할 수 있으면 유용합니다. 예를 들어 일반적으로 모든 Tomcat 관련 logger의 logging level을 변경할 수 있지만 최상위 패키지를 쉽게 기억할 수 없습니다.
이를 돕기 위해 Spring Environment
를 사용하면 logging group을 정의할 수 있습니다.
예를 들어 “tomcat” group을 application.properties
에 추가하여 정의하는 방법은 다음과 같습니다:
logging:
group:
tomcat: "org.apache.catalina,org.apache.coyote,org.apache.tomcat"
일단 정의되면 한 줄로 모든 그룹에 있는 모든 logger의 level을 변경할 수 있습니다:
logging:
level:
tomcat: "trace"
Spring Boot에는 즉시 사용할 수 있는 다음과 같은 사전 정의된 logging group이 포함되어 있습니다:
Name | Loggers |
---|---|
web |
|
sql |
|
1.7. Using a Log Shutdown Hook
application 종료 시 loggin resource를 해제하기 위해 JVM 종료 시 log system cleanup을 trigger 하는 shutdown hook이 제공됩니다.
이 shutdown hook은 application이 war 파일로 배포되지 않는 한 자동으로 등록됩니다.
application에 복잡한 context hierarchy가 있는 경우 요구 조건이 충족되지 않아 shutdown hook이 동작하지 않을 수 있습니다.
이런 경우 shutdown hook을 비활성화하고 logging system에 직접 처리하는 옵션을 사용합니다.
예를 들어 logback은 context selectors를 제공하여 각 logger를 자체 context에서 생성할 수 있습니다.
configprop:logging.register-shutdown-hook[] property를 사용하여 shutdown hook를 비활성화 할 수 있습니다.
false
로 설정하면 등록이 비활성화 됩니다.
application.properties
또는 application.yaml
파일에서 property를 설정할 수 있습니다.
logging:
register-shutdown-hook: false
1.8. Custom Log Configuration
다양한 loggin system은 classpath에 적절한 library를 포함하여 활성화할 수 있으며 classpath의 root 또는 Spring Environment
property: configprop:logging.config[] 에 지정된 위치에 적절한 configuration file을 제공하여 추가로 customize 할 수 있습니다.
org.springframework.boot.logging.LoggingSystem
system property를 사용하여 Spring Boot가 특정 logging system을 사용하도록 강제할 수 있습니다.
값은 LoggingSystem
구현의 명확한 class name이어야 합니다.
none
값을 사용하여 Spring Boot의 Logging configuration을 완전히 비활성화할 수도 있습니다.
logging은 ApplicationContext 가 만들어지기 이전 에 초기화되기 때문에 Spring @Configuration file의 @PropertySources 에서 logging을 설정할 수 없습니다.
logging system을 변경하거나 완전히 비활성화하는 유일한 방법은 System properties를 이용하는 것입니다.
|
logging system에 따라 다음 file이 load 됩니다:
Logging System | Customization |
---|---|
Logback |
|
Log4j2 |
|
JDK (Java Util Logging) |
|
가능한 경우 logging configuration에 -spring variants 을 사용하는 것이 좋습니다. (예를 들면 logback.xml 대신 logback-spring.xml ).
standard configuration location을 사용하는 경우 Spring은 log initialization을 완전히 제어할 수 없습니다.
|
Java Util Logging에 'executable jar’에서 실행할 때 문제를 일으키는 classloading issue가 있습니다. 가능하면 'executable jar’에서 실행할 때 피하는 것이 좋습니다. |
customization을 돕기 위해 다음 표에 설명된 대로 일부 다른 properties가 Spring Environment
에서 System properties로 전달됩니다.
Spring Environment | System Property | Comments |
---|---|---|
configprop:logging.exception-conversion-word[] |
|
The conversion word used when logging exceptions. |
configprop:logging.file.name[] |
|
If defined, it is used in the default log configuration. |
configprop:logging.file.path[] |
|
If defined, it is used in the default log configuration. |
configprop:logging.pattern.console[] |
|
The log pattern to use on the console (stdout). |
configprop:logging.pattern.dateformat[] |
|
Appender pattern for log date format. |
configprop:logging.charset.console[] |
|
The charset to use for console logging. |
configprop:logging.pattern.file[] |
|
The log pattern to use in a file (if |
configprop:logging.charset.file[] |
|
The charset to use for file logging (if |
configprop:logging.pattern.level[] |
|
The format to use when rendering the log level (default |
|
|
The current process ID (discovered if possible and when not already defined as an OS environment variable). |
logback을 사용하는 경우 다음 properties도 전달됩니다:
Spring Environment | System Property | Comments |
---|---|---|
configprop:logging.logback.rollingpolicy.file-name-pattern[] |
|
Pattern for rolled-over log file names (default |
configprop:logging.logback.rollingpolicy.clean-history-on-start[] |
|
Whether to clean the archive log files on startup. |
configprop:logging.logback.rollingpolicy.max-file-size[] |
|
Maximum log file size. |
configprop:logging.logback.rollingpolicy.total-size-cap[] |
|
Total size of log backups to be kept. |
configprop:logging.logback.rollingpolicy.max-history[] |
|
Maximum number of archive log files to keep. |
지원되는 모든 logging system은 configuration file을 parsing 할 때 system properties를 참조할 수 있습니다. `spring-boot.jar`의 default configuration을 참조하세요:
logging property에 placeholder를 사용하려면 기본 framework의 구문이 아닌 Spring Boot’s syntax 를 사용해야 합니다.
특히 Logback을 사용하는 경우 property name과 default value 사이에 |
2019-08-30 12:30:04.031 user:someone INFO 22174 --- [ nio-8080-exec-0] demo.Controller Handling authenticated request |
1.9. Logback Extensions
Spring Boot에는 advanced configuration에 도움이 되는 Logback에 대한 여러 extension이 포함되어 있습니다.
logback-spring.xml
configuration file에서 이러한 extension을 사용할 수 있습니다.
standard logback.xml configuration file은 너무 일찍 로드되기 때문에 이 file에서 extension을 사용할 수 없습니다.
logback-spring.xml 을 사용하거나 또는 configprop:logging.config[] property를 정의해야 합니다.
|
extension은 Logback의 configuration scanning과 함께 사용할 수 없습니다. 만약 이렇게 하려고 하면 configuration file을 변경하면 다음과 유사한 오류가 발생합니다. |
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]] ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]
1.9.1. Profile-specific Configuration
<springProfile>
태그는 active Spring Profile에 기반한 configuration section을 선택적으로 포함하거나 제외할 수 있습니다.
Profile section은 <configuration>
요소 내 모든 위치에서 지원됩니다.
name
attribute를 사용하여 대상 configuration profile을 지정할 수 있습니다.
<springProfile>
tag는 profile name(예를 들어 staging
) 또는 profile expression을 포함할 수 있습니다.
profile expression은 좀 더 복잡한 profile logic을 표현할 수 있습니다. (예: production & (eu-central | eu-west)
)
자세한 내용은 reference guide를 확인하세요.
다음 목록은 세 가지 sample profile을 보여줍니다.
<springProfile name="staging">
<!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>
<springProfile name="dev | staging">
<!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>
<springProfile name="!production">
<!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>
1.9.2. Environment Properties
<springProperty>
tag를 사용하면 logback 내에서 사용할 수 있도록 Spring Environment
의 properties를 노출할 수 있습니다.
이렇게 하면 Logback configuration에서 application.properties
file의 값에 접근하려는 경우 유용할 수 있습니다.
tag는 logback standard <property>
tag와 유사한 방식으로 동작합니다.
그러나 직접 value
를 지정하는 대신 property의 source
를 지정합니다( Environment
로 부터).
property를 local
scope 이외의 다른 곳에 저장해야 하는 경우 scope
attribute를 사용할 수 있습니다.
fallback value가 필요한 경우 ( Environment
에서 property를 설정하지 않은 경우) defaultValue
attribute를 사용할 수 있습니다.
다음 예에서는 Logback 내에서 사용할 properties를 노출하는 방법을 보여줍니다.
<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
<remoteHost>${fluentHost}</remoteHost>
...
</appender>
source 는 kebab case(예: my.property-name )로 지정해야 합니다.
그러나 완화된 규칙을 사용하여 property를 Environment 에 추가할 수 있습니다.
|
2. Testing
Spring Boot는 application을 테스트 할 때 도움이 되는 여러 utility와 annotation을 제공합니다.
테스트 지원은 두 개의 module로 제공됩니다: spring-boot-test
는 핵심 항목을 포함하고, spring-boot-test-autoconfigure
는 테스트를 위한 autoconfigure를 지원합니다.
대부분의 개발자는 Spring Boot test module과 JUnit Jupiter, AssertJ, Hamcrest 및 기타 여러 유용한 라이브러리를 가져오는 spring-boot-starter-test
"`Starter`"를 사용합니다.
JUnit4를 사용하는 테스트가 있는 경우 JUnit 5의 vintage engine을 사용하여 실행할 수 있습니다.
vintage engine을 사용하려면
|
spring-boot-starter-test
에 포함된 org.hamcrest:hamcrest
를 사용하며 hamcrest-core
는 제외됩니다. (hamcrest에 통합되었음)
2.1. Test Scope Dependencies
The spring-boot-starter-test
“Starter” 는 (test
scope
에서) 아래와 같은 라이브러리가 포함됩니다:
-
JUnit 5: Java applications 단위 테스트를 위한 사실상 표준
-
Spring Test & Spring Boot Test: Spring Boot applications을 위한 유틸리티 및 통합 테스트 지원.
-
AssertJ: A fluent assertion library.
-
Hamcrest: matcher objects의 라이브러리 (constraints 또는 predicates로 알려진).
-
Mockito: A Java mocking framework.
-
JSONassert: An assertion library for JSON.
-
JsonPath: XPath for JSON.
일반적으로 이러한 공통 라이브러리는 테스트를 작성할 때 유용합니다. 이러한 라이브러리가 필요하지 않으면 자체적으로 테스트 dependency를 추가하면 됩니다.
2.2. Testing Spring Applications
dependency injection의 주요 장점 중 하나는 단위 테스트하기 쉽게 코드를 만들 수 있다는 것입니다.
Spring을 사용하지 않더라도 new
operator를 사용하여 object를 인스턴스화 할 수 있습니다.
실제 dependency 대신 mock object 를 사용할 수도 있습니다.
종종 단위 테스트를 뛰어넘어 통합 테스트를 해야합니다. (Spring ApplicationContext
과 함께)
application을 배포하거나 다른 infrastructure와 연결할 필요 없이 통합 테스트를 수행할 수 있는 것이 유용합니다.
Spring Framework에는 이러한 통합 테스트를 위한 전용 test module이 포함되어 있습니다.
Spring Framework인 org.springframework:spring-test
를 바로 dependency 설정하거나 spring-boot-starter-test
“Starter” 를 통해 가져올 수 있습니다.
spring-test
module을 이전에 사용하지 않았다면 Spring Framework reference의 관련 section을 읽는 것으로 시작해야 합니다.
2.3. Testing Spring Boot Applications
Spring Boot application은 Spring ApplicationContext
이므로 vanilla Spring contenxt에서 일반적인 테스트를 하는 것보다 특별한 것은 없습니다.
Spring Boot의 외부 properties, logging 및 다른 기능은 기본적으로 SpringApplication 을 사용하여 생성하는 경우에만 context에 처리됩니다.
|
Spring Boot는 Spring Boot 기능이 필요할 때 표준 spring-test
@ContextConfiguration
annotation의 대안으로 사용할 수 있는 @SpringBootTest
annotation을 제공합니다.
이 annotation은 SpringApplication
을 통해 테스트에 사용된 ApplicationContext
를 생성 하는 방식으로 동작합니다.
@SpringBootTest
외에 더 구체적인 slice test를 위해 여러 개의 다른 annotation도 제공됩니다.
JUnit 4를 사용하는 경우 @RunWith(SpringRunner.class) 를 테스트에 추가해야하는 것을 잊지 마세요. 그렇지 않으면 annotation이 무시됩니다.
JUnit 5를 사용하는 경우 @SpringBootTest 와 다른 @…Test annotation이 이미 선언하고 있으므로 @ExtendWith(SpringExtension.class) 를 추가할 필요가 없습니다.
|
기본적으로 @SpringBootTest
는 server를 시작하지 않습니다.
@SpringBootTest
의 webEnvironment
attribute를 사용하여 테스트 수행 방법을 구체화 할 수 있습니다:
-
MOCK
(Default) : webApplicationContext
을 로드하고 mock web environment을 제공합니다. 이 annotation을 사용할 때 embeded server가 시작되지 않습니다. classpath에 web environment가 없는 경우, 이 mode는 web이 아닌 일반ApplicationContext
를 생성합니다.@AutoConfigureMockMvc
또는@AutoConfigureWebTestClient
와 함께 web application의 mock-based 테스트를 위해 사용할 수 있습니다. -
RANDOM_PORT
:WebServerApplicationContext
를 로드하고 실제 web environment를 제공합니다. embedded server가 시작되고 random port를 사용합니다. -
DEFINED_PORT
:WebServerApplicationContext
를 로드하고 실제 web environment를 제공합니다. embedded server가 (application.properties
에) 정의된 port 또는 default port인8080
으로 시작됩니다. -
NONE
:SpringApplication
을 사용하여ApplicationContext
를 로드하지만 web environment (mock or otherwise)는 전혀 제공하지 않습니다.
테스트가 @Transactional 인 경우 default로 각 테스트 method의 종료 시 transaction을 roll back합니다.
그러나 RANDOM_PORT 또는 DEFINED_PORT 와 함께 사용시 암시적으로 실제 servlet 환경을 제공하므로, HTTP client와 server는 별도의 thread에서 실행되므로 별도의 transcation에서 실행됩니다.
이 경우 server에서 시작된 transcation은 roll back 되지 않습니다.
|
webEnvironment = WebEnvironment.RANDOM_PORT 와 함께 @SpringBootTest 사용 시 application이 management server에 대해 다른 port를 사용하는 경우 별도의 random port로 management server를 시작합니다.
|
2.3.1. Detecting Web Application Type
Spring MVC를 사용할 수 있는 경우 일반 MVC 기반 application context가 구성됩니다. Spring WebFlux만 있는 경우 이를 감지하고 WebFlux 기반 application context를 구성합니다.
만약 둘다 있으면 Spring MVC가 우선합니다. 이 시나리오에서 reactive web application을 테스트하려면 configprop:spring.main.web-application-type[] property를 설정해야 합니다.
@SpringBootTest(properties = "spring.main.web-application-type=reactive")
class MyWebFluxTests { ... }
2.3.2. Detecting Test Configuration
Spring Test Framework에 익숙하다면 Spring @Configuration
를 로드하기 위해 @ContextConfiguration(classes=…)
를 사용하는데 익숙할 수 있습니다.
또는 테스트내에서 중첩 @Configuration
class를 자주 사용했을 수 있습니다.
Spring Boot application을 테스트할 때 이는 종종 필요하지 않습니다.
Spring Boot의 @*Test
annotation은 주요 configuration을 정의하지 않아도 자동으로 검색합니다.
검색 알고리즘은 @SpringBootApplication
또는 @SpringBootConfiguration
annotation이 달린 class를 테스트가 포함된 package에서 동작합니다.
코드를 합리적으로 구성하기만 하면 주요 구성이 대개 검색됩니다.
test annotation을 사용하여 application의 특정 부분을 테스트하는 경우 main method의 application class에 특정 영역에 특정 configuration 설정을 추가하지 않도록 해야합니다.
|
primary configuration을 customize하려는 경우 중첩된 @TestConfiguration
class를 사용할 수 있습니다.
application의 primary configuration 대신 사용되는 중첩된 @Configuration
class와 달리 중첩된 @TestConfiguration
는 application의 primary configuration에 추가로 적용됩니다.
Spring의 test framework는 test간 application context를 캐시합니다. 따라서 테스트가 동일한 configuration을 공유하는 한 (검색 방법에 관계 없이) 잠재적으로 시간이 많이 걸리는 context loading도 한 번만 발생합니다. |
2.3.3. Excluding Test Configuration
application에서 component scan을 사용하는 경우 (예: @SpringBootApplication
또는 @ComponentScan
를 사용하는 경우) 특정 테스트용으로만 생성한 top-level copnfiguration class가 실수로 모든 곳에서 선택될 수 있습니다.
앞서 살펴본 것처럼 @TestConfiguration
은 test의 inner class에서 primary configuration을 customize 하는데 사용할 수 있습니다.
top-level class에 배치될 떄 @TestConfiguration
은 src/test/java
의 class를 검색으로 선택할 수 없음을 나타냅니다.
그런 다음 아래 예제와 같이 필요한 위치의 해당 class를 명시적으로 import 할 수 있습니다.
@SpringBootTest
@Import(MyTestsConfiguration.class)
class MyTests {
@Test
void exampleTest() {
...
}
}
만약 @ComponentScan 를 직접 사용한다면 (즉 @SpringBootApplication 을 통하지 않은 경우) TypeExcludeFilter 를 등록해야 합니다.
자세한 내용은 the Javadoc을 참조하세요.
|
2.3.4. Using Application Arguments
application이 arguments를 예상하는 경우 args
attribute를 사용하여 @SpringBootTest
에 주입하도록 할 수 있습니다.
@SpringBootTest(args = "--app.test=one")
class ApplicationArgumentTests {
@Test
void applicationArgumentsPopulated(@Autowired ApplicationArguments args) {
assertThat(args.getOptionNames()).containsOnly("app.test");
assertThat(args.getOptionValues("app.test")).containsOnly("one");
}
}
2.3.5. Testing with a mock environment
default로 @SpringBootTest
는 server를 시작하지 않습니다.
만약 mock environment에 테스트하려는 web endpoint가 있는 경우 다음 예제와 같이 MockMvc
를 추가로 구성할 수 있습니다:
@SpringBootTest
@AutoConfigureMockMvc
class MockMvcTests {
@Test
void exampleTest(@Autowired MockMvc mvc) throws Exception {
mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Hello World"));
}
}
만약 web layer에만 집중하고 전체 ApplicationContext 를 시작하지 않으려면 @WebMvcTest 를 대신 사용하는 것을 고려하세요.
|
또는 WebTestClient
를 다음 예제와 같이 구성할 수 있습니다.
@SpringBootTest
@AutoConfigureWebTestClient
class MockWebTestClientTests {
@Test
void exampleTest(@Autowired WebTestClient webClient) {
webClient.get().uri("/").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("Hello World");
}
}
mock environment에서 테스트 하는 것은 일반적으로 전체 Servlet container를 실행하는 것보다 빠릅니다. 그러나 mocking은 Spring MVC layer에서 발생하기 때문에 하위 수준의 Servlet container 동작에 의존하는 코드는 MockMvc로 직접 테스트 할 수 없습니다. 예를 들어 Spring Boot의 오류 처리는 Servlet container에서 제공하는 “error page” 지원을 기반으로 합니다. 이것은 MVC layer가 기대한대로 exception을 throw하고 처리하는 것을 테스트 할 수 있지만 특정 custom error page가 렌더링되었는지 직접 테스트 할 수는 없습니다. 이러한 lover-level의 문제를 테스트해야 하는 경우 다음 섹션에 섦명된 대로 완전히 실행중인 서버를 시작할 수 있습니다. |
2.3.6. Testing with a running server
전체 실행 서버를 시작해야하는 경우 random port를 사용하는 것이 좋습니다.
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
를 사용하는 경우 테스트가 실행될 때마다 사용 가능한 port가 무작위로 선택됩니다.
@LocalServerPort
annotation은 사용하는 실제 port 주입 테스트에 사용됩니다.
편의를 위해 시작된 서버에 대한 REST 호출을 수행해야 하는 테스트는 @Autowire
를 추가로 WebTestClient
로 할 수 있는데, 이 client는 실행 중인 서버에 대한 상대 link를 확인하고 응답을 확인하기 위한 전용 API를 제공합니다.
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class RandomPortWebTestClientTests {
@Test
void exampleTest(@Autowired WebTestClient webClient) {
webClient.get().uri("/").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("Hello World");
}
}
이 설정은 classpath에 spring-webflux
를 필요로 합니다.
webflux를 추가할 수 없거나 추가하지 않은 경우 Spring Boot는 다음과 같은 TestRestTemplate
기능도 제공합니다:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class RandomPortTestRestTemplateTests {
@Test
void exampleTest(@Autowired TestRestTemplate restTemplate) {
String body = restTemplate.getForObject("/", String.class);
assertThat(body).isEqualTo("Hello World");
}
}
2.3.7. Customizing WebTestClient
WebTestClient
bean을 customize하려면 WebTestClientBuilderCustomizer
bean을 구성하면 됩니다.
WebTestClient.Builder
로 호출된 bean은 WebTestClient
을 만드는데 사용됩니다.
2.3.8. Using JMX
test context framework가 context를 cache 하기 때문에 JMX는 default로 비활성화되어 동일한 구성 요소가 동일한 도메인에 등록되지 않도록 합니다.
만약 테스트가 MBeanServer
에 접근해야 하는 경우 dirty mark도 고려해야 합니다.
@SpringBootTest(properties = "spring.jmx.enabled=true")
@DirtiesContext
class SampleJmxTests {
@Autowired
private MBeanServer mBeanServer;
@Test
void exampleTest() throws MalformedObjectNameException {
assertThat(this.mBeanServer.getDomains()).contains("java.lang");
// ...
}
}
2.3.9. Using Metrics
classpath와 관계없이 @SpringBootTest
를 사용할 때 지원되는 in-memory를 제외한 meter registry는 자동으로 구성되지 않습니다.
통합 테스트의 일부로 metric을 다른 backend로 내보내야 하는 경우 @AutoConfigureMetrics
annotation을 추가합니다.
2.3.10. Mocking and Spying Beans
테스트를 실행할 때 때때로 application context 내에서 득정 구성 요소를 mock으로 처리해야 하는 경우가 있습니다. 예를 들면 개발 중에 사용할 수 없는 일부 원격 서비스에 대한 facade가 있을 수 있습니다. mocking은 실제 환경에서 trigger 하기 어려울 수 있는 실패를 시뮬레이션 하는 경우에도 유용할 수 있습니다.
Spring Boot는 ApplicationContext
내부 bean에 대한 Mockito mock을 정의한는데 사용하기 위한 @MockBean
annotation을 포함하고 있습니다.
annotation을 사용하여 새 bean을 추가하거나 기존 single bean 정의를 바꿀 수 있습니다.
annotation은 test class, test class내의 field 또는 @Configuration
class와 field에서 직접 사용할 수 있습니다.
field에서 사용하면 생성된 mock instance도 inject 됩니다.
mock bean은 각 테스트 method 실행 이후 reset 됩니다.
테스트에서 Spring Boot의 test annotation (예를 들면
|
다음 예제는 기존 RemoteService
bean을 mock 구현으로 대체합니다.
@SpringBootTest
class MyTests {
@MockBean
private RemoteService remoteService;
@Autowired
private Reverser reverser;
@Test
void exampleTest() {
// RemoteService has been injected into the reverser bean
given(this.remoteService.someCall()).willReturn("mock");
String reverse = reverser.reverseSomeCall();
assertThat(reverse).isEqualTo("kcom");
}
}
@MockBean 은 application context가 refresh되는 동안 실행되는 bean의 동작을 mock 처리하는데 사용할 수 없습니다.
test가 실행될 때 application context refresh가 완료되어 mock behavior가 구성되기에는 너무 늦습니다.
이런 경우 @Bean method를 생성하고 구성하여 mock을 만다는 것이 좋습니다.
|
또한 @SpyBean
을 사용하여 Mockito spy
로 기존 beand을 wrapping 할 수 있습니다.
자세한 내용은 Javadoc을 참조하세요
scoped bean 생성같은 CGLIB proxy는 proxy된 method를 final 로 선언합니다.
이는 default configuration에서 final method를 mock 처리하거나 spy 처리 할 수 없기 때문에 올바르게 작동하지 않습니다.
만약 이런 bean을 mock 또는 spy 처리하고 싶다면 org.mockito:mockito-inline 를 application의 test dependencies에 추가하여 Mockito가 inline mock maker를 사용하도록 구성합니다.
|
Spring의 test framework는 test 간 applciation context를 cache하고 동일한 구성을 공유하는 테스트를 위해 context를 재사용하지만 @MockBean 또는 @SpyBean 의 사용은 cache key에 영향을 미쳐 context를 늘릴 가능성이 높습니다.
|
만약 name으로 parameter를 참조하는 @Cacheable method가 있는 bean을 감시하기 위해 @SpyBean 을 사용하는 경우 application은 -parameters 로 compile 되어야 합니다.
이렇게 하면 bean이 감시된 후 caching infrastructure에서 parameter name을 사용할 수 있습니다.
|
@SpyBean 을 사용하여 Spring의 proxy 된 bean을 감시할 때 given 이나 when 을 사용하여 expectations을 설정할 때처럼 경우에 따라 Spring의 proxy를 제거해야 할 수 있습니다.
그렇게 하려면 AopTestUtils.getTargetObject(yourProxiedSpy) 를 사용하세요
|
2.3.11. Auto-configured Tests
Spring Boot의 auto-configuration sytstem은 application에서 동작하지만 때로는 테스트에 너무 많은 경우가 있습니다. application의 "`slice`"를 테스트 하는데 필요한 configuration 부분만 로드하면 도움이 되는 경우가 많습니다. 예를 들면, Spring MVC controller가 URL을 올바르게 mapping하는지 테스트하고 해당 테스트에 dastabase 호출을 포함하지 않거나 또는 JPA entity를 테스트 하고 싶을 때 web layer에 관심이 없는 경우가 있습니다.
spring-boot-test-autoconfigure
module은 이러한 “slices” 를 자동으로 구성하는데 사용할 수 있는 여러 annotation이 포함되어 있습니다.
각각은 auto-configuration 설정을 customize하는데 사용되는 ApplicationContext
과 하나 이상의 @AutoConfigure…
annotations을 로드하는 @…Test
annotation으로 제공되며 비슷한 방식으로 동작합니다.
각 slice는 component scan을 적절한 component로 제한하고 매우 제한된 auto-configuration class를 로드합니다.
그 중 하나를 제외해야하는 경우 대부분의 @…Test annotations은 excludeAutoConfiguration attribute를 제공합니다.
또는 @ImportAutoConfiguration#exclude 를 사용할 수 있습니다.
|
하나의 테스트에서 여러 개의 @…Test annotations 을 사용하여 여러 "`slices`"를 포함하는 것은 지원되지 않습니다.
민액 여러 "`slices`"가 필요한 경우 @…Test annotations 중 하나를 선택하고 다른 "`slices`"의 @AutoConfigure… annotations 을 직접 포함해야 합니다.
|
standard @SpringBootTest annotation과 함께 @AutoConfigure… annotations을 사용할 수도 있습니다.
application을 “slicing” 하는 데 관심이 없지만 auto-configured test bean 중 일부를 원하는 경우 이 조합을 사용할 수 있습니다.
|
2.3.12. Auto-configured JSON Tests
object JSON serialization 과 deserialization가 예상대로 동작하는지 테스트하려면 @JsonTest
annotation을 사용할 수 있습니다.
@JsonTest
는 다음 library 중 하나가 될 수 있는 사용가능한 JSON mapper를 auto-configure 처리합니다.
-
Jackson
ObjectMapper
, any@JsonComponent
beans and any JacksonModule
s -
Gson
-
Jsonb
@JsonTest 에 의해 활성화된 auto-configuration 목록은 appendix 에서 찾을 수 있습니다.
|
auto-configuration 요소를 구성해야 하는 경우 @AutoConfigureJsonTesters
annotation을 사용할 수 있습니다.
Spring Boot는 JSON이 예상한 대로 표시되는지 확인하기 위해 JSONASsert와 JsonPath library와 함께 동작하는 AssertJ-based helper가 포함되어 있습니다.
JacksonTester
, GsonTester
, JsonbTester
, 및 BasicJsonTester
class는 각각 Jackson, Gson, Jsonb 및 String에 사용할 수 있습니다.
@JsonTest
를 사용할 때 test class의 helper field를 @Autowired
할 수 있습니다.
다음 예제는 Jackson의 test class를 보여줍니다:
@JsonTest
class MyJsonTests {
@Autowired
private JacksonTester<VehicleDetails> json;
@Test
void testSerialize() throws Exception {
VehicleDetails details = new VehicleDetails("Honda", "Civic");
// Assert against a `.json` file in the same package as the test
assertThat(this.json.write(details)).isEqualToJson("expected.json");
// Or use JSON path based assertions
assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make")
.isEqualTo("Honda");
}
@Test
void testDeserialize() throws Exception {
String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}";
assertThat(this.json.parse(content))
.isEqualTo(new VehicleDetails("Ford", "Focus"));
assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford");
}
}
JSON helper class는 표준 단위 테스트에 직접 사용할 수도 있습니다.
그렇게 하려면 @JsonTest 를 사용하지 않는 경우 @Before method에 helper의 initFields method를 호출합니다.
|
Spring Boot의 AssertJ-based helpers를 사용하여 주어진 JSON path에서 number value를 assert하는 경우 type에 따라 isEqualTo를 사용하지 못할 수 있습니다.
대신 AssertJ의 satisfies
를 사용하여 값이 지정된 조건과 일치한다고 assert 할 수 있습니다.
예를 들어 다음 예제에서는 실제 숫자가 0.01
의 offset 내에서 0.15
에 가까운 float value로 assert 할 수 있습니다.
assertThat(json.write(message))
.extractingJsonPathNumberValue("@.test.numberValue")
.satisfies((number) -> assertThat(number.floatValue()).isCloseTo(0.15f, within(0.01f)));
2.3.13. Auto-configured Spring MVC Tests
Spring MVC controller가 예상대로 동작하는지 테스트하려면 @WebMvcTest
annotation을 사용할 수 있습니다.
@WebMvcTest
는 Spring MVC infrastructor를 auto-configure 하고 scanned bean을 @Controller
, @ControllerAdvice
, @JsonComponent
, Converter
, GenericConverter
, Filter
, HandlerInterceptor
, WebMvcConfigurer
, 및 HandlerMethodArgumentResolver
로 제한합니다.
@WebMvcTest
annotation이 사용된 경우 일반 @Component
와 @ConfigurationProperties
bean은 scan 되지 않습니다.
@EnableConfigurationProperties
는 @ConfigurationProperties
bean을 포함하는데 사용할 수 있습니다.
@WebMvcTest 에서 활성화된 auto-configuration 목록 설정은 부록(appendix)에서 찾을 수 있습니다.
|
Jackson Module 같은 확장 component 등록이 필요한 경우 테스트에 @Import 를 사용하여 추가적인 configuration class를 import 할 수 있습니다.
|
종종 @WebMvcTest
는 single controller로 제한되며 @MockBean
과 함께 사용되어 필요한 collaborator에게 mock 구현을 제공합니다.
@WebMvcTest
또한 MockMvc
를 auto-configure합니다.
Mock MVC는 전체 HTTP server를 시작할 필요 없이 MVC Controller를 빠르게 테스트할 수 있는 강력한 방법을 제공합니다.
(@SpringBootTest 같은) non-@WebMvcTest 에서도 MockMvc 를 @AutoConfigureMockMvc annotation을 통해 auto-configure 할 수도 있습니다.
아래 예제는 MockMvc 를 사용합니다:
|
@WebMvcTest(UserVehicleController.class)
class MyControllerTests {
@Autowired
private MockMvc mvc;
@MockBean
private UserVehicleService userVehicleService;
@Test
void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk()).andExpect(content().string("Honda Civic"));
}
}
auto-configuration의 element를 구성해야 하는 경우 (예: servlet filter를 적용해야 하는 경우) @AutoConfigureMockMvc annotation에서 attribute를 사용할 수 있습니다.
|
HtmlUnit 또는 Selenium을 사용하는 경우 auto-configuration은 HtmlUnit WebClient
bean 및/또는 Selenuum WebDriver
bean도 제공합니다.
다음 예제는 HtmlUnit을 사용합니다:
@WebMvcTest(UserVehicleController.class)
class MyHtmlUnitTests {
@Autowired
private WebClient webClient;
@MockBean
private UserVehicleService userVehicleService;
@Test
void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
HtmlPage page = this.webClient.getPage("/sboot/vehicle.html");
assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic");
}
}
기본적으로 Spring Boot는 WebDriver bean을 특별한 "`scope`"에 넣어 각 테스트 후 driver가 종료되고 새 instance가 inject되도록 합니다.
이 동작을 원하지 않는 경우 @Scope("singleton") 를 WebDriver @Bean 에 추가할 수 있습니다.
|
Spring Boot에 의해 생성된 webDriver scope 는 동일한 이름의 사용자 정의 scope를 대체합니다.
만약 자체 webDriver scope를 정의하면 `@WebMvcTest`를 사용할 때 동작이 중지될 수 있습니다.
|
만약 classpath에 Spring Security가 있다면 @WebMvcTest
는 WebSecurityConfigurer
bean을 scan합니다.
이러한 테스트에 대해 security를 완전히 비활성화하는 대신 Spring Security의 test 지원을 사용할 수 있습니다.
Spring Security의 MockMvc
지원에 대한 좀더 자세한 내용은 howto.html how-to section에서 찾을 수 있습니다.
때때로 Spring MVC 테스트를 작성하는 것만으로 충분하지 않습니다. Spring Boot는 실제 서버로 전체 end-to-end 테스트를 실행하는데 도움이 됩니다. |
2.3.14. Auto-configured Spring WebFlux Tests
Spring WebFlux controllers가 예상대로 작동하는지 테스트하려면 @WebFluxTest
annotation을 사용할 수 있습니다.
@WebFluxTest
는 Spring WebFlux infrastructure를 auto-configure 하고 scanned bean을 @Controller
, @ControllerAdvice
, @JsonComponent
, Converter
, GenericConverter
, WebFilter
및 WebFluxConfigurer
로 제한합니다.
@WebFluxTest
annotation이 사용된 경우 표준 @Component
와 @ConfigurationProperties
beans은 scan 되지 않습니다.
@EnableConfigurationProperties
는 @ConfigurationProperties
bean을 포함하는데 사용할 수 있습니다.
@WebFluxTest 로 활성화된 auto-configuration 목록은 부록(appendix)에서 확인할 수 있습니다.
|
만약 Jackson`Module` 같은 추가 component를 등록해야 하는 경우 test에서 @Import 를 사용하여 추가 configuration class를 import 할 수 있습니다.
|
종종 @WebFluxTest
는 single controller로 제한되며 @MockBean
과 함께 사용되어 필요한 collaborator에게 mock 구현을 제공합니다.
@WebFluxTest
는 또한 WebTestClient
를 auto-configure합니다. 이 client는 전체 HTTP server를 시작할 필요 없이 WebFlux controller를 빠르게 테스트할 수 있는 강력한 방법을 제공합니다.
(@SpringBootTest 같은) non-@WebFluxTest 에서도 WebTestClient 를 @AutoConfigureWebTestClient annotation을 통해 auto-configure 할 수도 있습니다.
다음 예제는 @WebFluxTest 와 WebTestClient 를 모두 사용하는 경우입니다:
|
@WebFluxTest(UserVehicleController.class)
class MyControllerTests {
@Autowired
private WebTestClient webClient;
@MockBean
private UserVehicleService userVehicleService;
@Test
void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.webClient.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN)
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("Honda Civic");
}
}
mock web application에서 WebTestClient 를 사용하는 것은 현재 WebFlux에서만 작동하므로 이 설정은 현재 WebFlux application에서만 지원됩니다.
|
@WebFluxTest 는 functional web framework를 통해 등록된 경로를 감지할 수 없습니다.
context에서 RouterFunction bean을 테스트하려면 @Import 를 통해 직접 RouterFunction 을 가져오거나 @SpringBootTest 를 사용하는 것이 좋습니다.
|
@WebFluxTest 는 SecurityWebFilterChain type의 @Bean 을 통해 등록된 custom security configuration을 감지할 수 없습니다.
테스트에 포함하려면 @Import 를 통해 bean을 등록하는 configuration을 import하거나 @SpringBootTest 를 사용해야 합니다.
|
때때로 Spring WebFlux 테스트를 작성하는 것만으로 충분하지 않습니다. Spring Boot는 실제 서버로 전체 end-to-end 테스트를 실행하는데 도움이 됩니다. |
2.3.15. Auto-configured Data Cassandra Tests
Cassandra application을 테스트하는데 @DataCassandraTest
를 사용할 수 있습니다.
기본적으로 CassandraTemplate
를 구성하고 @Table
classe를 scan 하고 Spring Data Cassandra repository를 구성합니다.
@DataCassandraTest
annotation 이 사용될 때 일반 @Component
와 @ConfigurationProperties
bean은 scan되지 않습니다.
@EnableConfigurationProperties
을 사용하여 @ConfigurationProperties
bean을 포함할 수 있습니다.
(Spring Boot에서 Cassandra를 사용하는 방법에 대한 자세한 내용은 선행 챕터의 "[boot-features-cassandra]" 를 참조하세요.)
@DataCassandraTest 로 활성화한 auto-configuration 설정 목록은 부록 (appendix) 에서 확인할 수 있습니다.
|
다음 예제는 Spring Boot에일 Cassandra 테스트를 사용하기 위한 일반적인 설정을 보여줍니다:
@DataCassandraTest
class ExampleDataCassandraTests {
@Autowired
private YourRepository repository;
//
}
2.3.16. Auto-configured Data JPA Tests
@DataJpaTest
annotation을 사용하여 JPA application을 테스트할 수 있습니다.
기본적으로 @Entity
class를 scan 하고 Spring Data repository를 구성합니다.
classpath에 embedded database가 사용 가능한 경우 하나의 database도 구성됩니다.
SQL query는 기본적으로 spring.jpa.show-sql
property를 true
로 설정하여 기록됩니다.
annotation의 showSql()
attribute를 사용하여 비활성화 할 수 있습니다.
@DataJpaTest
annotation 이 사용될 때 일반 @Component
와 @ConfigurationProperties
bean은 scan되지 않습니다.
@EnableConfigurationProperties
는 @ConfigurationProperties
bean을 포함하는데 사용될 수 있습니다.
@DataJpaTest 로 활성화된 auto-configuration 구성 목록은 부록(appendix)에서 확인할 수 있습니다.
|
기본적으로 data JPA 테스트는 transactional이며 각 테스트가 끝날 때 roll back 됩니다. 자세한 내용은 Spring Framework 참조 문서의 관련 section울 참조하세요. 원하지 않을 경우 다음과 같이 테스트 또는 전체 class에 대해 transaction 관리를 비활성화 할 수 있습니다:
@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class ExampleNonTransactionalTests {
}
Data JPA 테스트는 테스트를 위해 특별히 설계된 JPA EntityManager
의 대안을 제공하는 TestEntityManager
bean을 inject 할 수 있습니다.
@DataJpaTest
instances 외부에서 TestEntityManager
를 사용하려는 경우 @AutoConfigureTestEntityManager
annotation을 사용할 수 있습니다.
필요한 경우 JdbcTemplate
도 사용할 수 있습니다.
다음 예제는 @DataJpaTest
annotation을 사용하는 경우를 보여줍니다:
@DataJpaTest
class ExampleRepositoryTests {
@Autowired
private TestEntityManager entityManager;
@Autowired
private UserRepository repository;
@Test
void testExample() throws Exception {
this.entityManager.persist(new User("sboot", "1234"));
User user = this.repository.findByUsername("sboot");
assertThat(user.getUsername()).isEqualTo("sboot");
assertThat(user.getVin()).isEqualTo("1234");
}
}
In-memory embedded databases는 빠르고 설치가 필요하지 않기 때문에 일반적으로 테스트에 적합합니다.
그러나 실제 데이터베이스에 대해 테스트를 실행하려는 경우 다음 예제와 같이 @AutoConfigureTestDatabase
annotation을 사용할 수 있습니다:
@DataJpaTest
@AutoConfigureTestDatabase(replace=Replace.NONE)
class ExampleRepositoryTests {
// ...
}
2.3.17. Auto-configured JDBC Tests
@JdbcTest
는 @DataJpaTest
와 비슷하지만 Spring Data JDBC를 사용하지 않고 DataSource
만 필요한 테스트에 사용됩니다.
기본적으로 in-memory embedded database와 JdbcTemplate
를 구성합니다.
@JdbcTest
annotation이 사용될 때 일반 @Component
과 @ConfigurationProperties
bean은 scan되지 않습니다.
@EnableConfigurationProperties
를 사용하여 @ConfigurationProperties
bean을 포함할 수 있습니다.
@JdbcTest 로 활성화된 auto-configuration 목록은 부록(appendix)에서 확인할 수 있습니다.
|
기본적으로 JDBC 테스트는 transactional이며 각 테스트가 끝날 때 roll back 됩니다. 자세한 내용은 Spring Framework 참조 문서의 관련 section을 참조하세요. 원하지 않을 경우 다음과 같이 테스트 또는 전체 class에 대해 transaction 관리를 비활성화 할 수 있습니다:
@JdbcTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class ExampleNonTransactionalTests {
}
만약 실제 데이터베이스에 대해 테스트를 실행하려는 경우 DataJpaTest
와 동일하게 @AutoConfigureTestDatabase
annotation을 사용할 수 있습니다:
("Auto-configured Data JPA Tests" 참조)
2.3.18. Auto-configured Data JDBC Tests
@DataJdbcTest
는 @JdbcTest
와 비슷하지만 Spring Dasta JDBC repository를 사용하는 테스트용입니다.
기본적으로 in-memory embedded database와 JdbcTemplate
, Spring Data JDBC repository를 구성합니다.
@DataJdbcTest
annotation 이 사용될 때 일반 @Component
및 @ConfigurationProperties
bean은 scan되지 않습니다.
@EnableConfigurationProperties
를 사용하여 @ConfigurationProperties
bean을 포함할 수 있습니다.
@DataJdbcTest 로 활성화된 auto-configuration 목록은 부록(appendix)에서 확인할 수 있습니다.
|
기본적으로 Data JDBC 테스트는 transactional이며 각 테스트가 끝날 때 roll back 됩니다. 자세한 내용은 Spring Framework 참조 문서의 관련 section을 참조하세요. 원하지 않을 경우 JDBC example에서 보여진 것처럼 테스트 또는 전체 테스트 class에 대해 transaction management를 비활성화 할 수 있습니다.
실제 데이터베이스에 대해 테스트를 실행하는 것을 선호하는 경우 DataJpaTest
와 동일하게 @AutoConfigureTestDatabase
annotation을 사용할 수 있습니다:
("Auto-configured Data JPA Tests" 참조)
2.3.19. Auto-configured jOOQ Tests
@JdbcTest
와 비슷한 방식으로 @JooqTest
를 jOOQ 관련 테스트에 사용할 수 있습니다.
jOOQ는 database schema와 일치하는 java-based schema에 크게 의존하므로 기존 DataSource
가 사용됩니다.
in-memory database로 변경하려면 @AutoConfigureTestDatabase
을 사용하여 해당 설정을 재정의할 수 있습니다.
(Spring Boot와 함께 jOOQ를 사용하는 방법에 대한 자세한 내용은 선행 챕터의 "[boot-features-jooq]" 을 참조하세요.)
@JooqTest
annotation이 사용될 때 일반 @Component
및 @ConfigurationProperties
bean은 scan되지 않습니다.
@EnableConfigurationProperties
를 사용하여 @ConfigurationProperties
bean을 포함할 수 있습니다.
@JooqTest 로 활성화된 auto-configuration 목록은 부록(appendix)에서 확인할 수 있습니다.
|
@JooqTest
는 DSLContext
을 구성합니다.
다음 예제는 @JooqTest
annotation을 사용하는 경우를 보여줍니다:
@JooqTest
class ExampleJooqTests {
@Autowired
private DSLContext dslContext;
}
기본적으로 JOOQ 테스트는 transactional이며 각 테스트가 끝날 때 roll back 됩니다. 원하지 않을 경우 JDBC example에서 보여진 것처럼 테스트 또는 전체 테스트 class에 대해 transaction management를 비활성화 할 수 있습니다.
2.3.20. Auto-configured Data MongoDB Tests
MongoDB applications을 테스트 하는데 @DataMongoTest
를 사용할 수 있습니다.
기본적으로 (가능한 경우) in-memory embedded MongoDB을 구성하며 MongoTemplate
을 구성하고 @Document
class를 scan 하며 Spring Data MongoDB repository를 구성합니다.
@DataMongoTest
annotation이 사용될 때 일반 @Component
및 @ConfigurationProperties
bean은 scan되지 않습니다.
@EnableConfigurationProperties
를 사용하여 @ConfigurationProperties
bean을 포함할 수 있습니다.
(Spring Boot와 함께 MongoDB를 사용하는 방법에 대한 자세한 내용은 선행 챕터의 "[boot-features-mongodb]" 을 참조하세요.)
@DataMongoTest 로 활성화된 auto-configuration 목록은 부록(appendix)에서 확인할 수 있습니다.
|
다음 예제는 @DataMongoTest
annotation을 사용하는 경우를 보여줍니다:
@DataMongoTest
class ExampleDataMongoTests {
@Autowired
private MongoTemplate mongoTemplate;
//
}
In-memory embedded MongoDB는 빠르고 개발자 설치가 필요하지 않기 때문에 일반적으로 테스트에 적합합니다. 그러나 실제 MongoDB server에 대해 테스트를 실행하려면 다음 예와 같이 embedded MongoDB auto-configuration을 제외해야 합니다:
@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)
class ExampleDataMongoNonEmbeddedTests {
}
2.3.21. Auto-configured Data Neo4j Tests
Neo4j applications을 테스트하기 위해 @DataNeo4jTest
을 사용할 수 있습니다.
기본적으로 @Node
class를 scan하고 Spring Data Neo4j repository를 구성합니다.
@DataNeo4jTest
annotation이 사용될 때 일반 @Component
및 @ConfigurationProperties
bean은 scan되지 않습니다.
@EnableConfigurationProperties
를 사용하여 @ConfigurationProperties
bean을 포함할 수 있습니다.
(Spring Boot와 함께 Neo4J를 사용하는 방법에 대한 자세한 내용은 선행 챕터의 "[boot-features-neo4j]" 을 참조하세요.)
@DataNeo4jTest 로 활성화된 auto-configuration 목록은 부록(appendix)에서 확인할 수 있습니다.
|
다음 예제는 Spring Boot에서 Neo4J를 테스트 하기 위한 일반적인 설정을 보여줍니다:
@DataNeo4jTest
class ExampleDataNeo4jTests {
@Autowired
private YourRepository repository;
//
}
기본적으로 Data Neo4j 테스트는 transactional이며 각 테스트가 끝날 때 roll back 됩니다. 자세한 내용은 Spring Framework 참조 문서의 관련 section을 참조하세요. 원하지 않을 경우 다음과 같이 테스트 또는 전체 테스트 class에 대해 transaction management를 비활성화 할 수 있습니다:
@DataNeo4jTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class ExampleNonTransactionalTests {
}
reactive access에서 Transactional 테스트는 지원되지 않습니다.
이 경우 위에 설명한 대로 @DataNeo4jTest 테스트를 구성해야 합니다.
|
2.3.22. Auto-configured Data Redis Tests
Redis applications을 테스트하기 위해 @DataRedisTest
를 사용할 수 있습니다.
기본적으로 @RedisHash
class를 scan하고 Spring Data Redis repository를 구성합니다.
@DataRedisTest
annotation이 사용될 때 일반 @Component
및 @ConfigurationProperties
bean은 scan되지 않습니다.
@EnableConfigurationProperties
를 사용하여 @ConfigurationProperties
bean을 포함할 수 있습니다.
(Spring Boot와 함께 Redis를 사용하는 방법에 대한 자세한 내용은 선행 챕터의 "[boot-features-redis]" 을 참조하세요.)
@DataRedisTest 로 활성화된 auto-configuration 목록은 부록(appendix)에서 확인할 수 있습니다.
|
다음 예제는 @DataRedisTest
annotation을 사용하는 경우를 보여줍니다:
@DataRedisTest
class ExampleDataRedisTests {
@Autowired
private YourRepository repository;
//
}
2.3.23. Auto-configured Data LDAP Tests
LDAP applications을 테스트하기 위해 @DataLdapTest
를 사용할 수 있습니다.
기본적으로 (가능한 경우) in-memory embedded LDAP을 구성하고 LdapTemplate`을 구성하고 `@Entry
class를 scan하고 Spring Data LDAP repository를 구성합니다.
@DataLdapTest
annotation이 사용될 때 일반 @Component
및 @ConfigurationProperties
bean은 scan되지 않습니다.
@EnableConfigurationProperties
를 사용하여 @ConfigurationProperties
bean을 포함할 수 있습니다.
(Spring Boot와 함께 LDAP를 사용하는 방법에 대한 자세한 내용은 선행 챕터의 "[boot-features-ldap]" 을 참조하세요.)
@DataLdapTest 로 활성화된 auto-configuration 목록은 부록(appendix)에서 확인할 수 있습니다.
|
다음 예제는 @DataLdapTest
annotation을 사용하는 경우를 보여줍니다:
@DataLdapTest
class ExampleDataLdapTests {
@Autowired
private LdapTemplate ldapTemplate;
//
}
In-memory embedded LDAP은 빠르고 개발자 설치가 필요하지 않기 때문에 일반적으로 테스트에 적합합니다. 그러나 실제 LDAP server에 대해 테스트를 실행하려면 다음 예와 같이 embedded LDAP auto-configuration을 제외해야 합니다:
@DataLdapTest(excludeAutoConfiguration = EmbeddedLdapAutoConfiguration.class)
class ExampleDataLdapNonEmbeddedTests {
}
2.3.24. Auto-configured REST Clients
REST client를 테스트하기 위해 @RestClientTest
annotation을 사용할 수 있습니다.
기본적으로 Jackson, GSON 및 Jsonb 지원을 auto-configure하고 RestTemplateBuilder
를 구성하고 MockRestServiceServer
지원을 추가합니다.
@RestClientTest
annotation이 사용될 때 일반 @Component
및 @ConfigurationProperties
bean은 scan되지 않습니다.
@EnableConfigurationProperties
를 사용하여 @ConfigurationProperties
bean을 포함할 수 있습니다.
@RestClientTest 로 활성화된 auto-configuration 목록은 부록(appendix)에서 확인할 수 있습니다.
|
다음 예제와 같이 @RestClientTest
의 value
또는 components
attribute를 사용하여 테스트할 bean을 지정해야 합니다:
@RestClientTest(RemoteVehicleDetailsService.class)
class ExampleRestClientTest {
@Autowired
private RemoteVehicleDetailsService service;
@Autowired
private MockRestServiceServer server;
@Test
void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails()
throws Exception {
this.server.expect(requestTo("/greet/details"))
.andRespond(withSuccess("hello", MediaType.TEXT_PLAIN));
String greeting = this.service.callRestService();
assertThat(greeting).isEqualTo("hello");
}
}
2.3.25. Auto-configured Spring REST Docs Tests
@AutoConfigureRestDocs
annotation을 사용하여 Mock MVC, REST Assured 또는 WebTestClient로 테스트에서 Spring REST Docs를 사용할 수 있습니다.
Spring REST Docs애서 JUnit extension은 필요하지 않습니다.
@AutoConfigureRestDocs
는 기본 output directory(Maven을 사용하는 경우 target/generated-snippets
, Gradle을 사용하는 경우 build/generated-snippets
)를 재정의 하는데 사용할 수 있습니다.
또한 문서화된 URI에서 나타나는 host, scheme 및 port를 구성하는 데 사용할 수도 있습니다.
Auto-configured Spring REST Docs Tests with Mock MVC
@AutoConfigureRestDocs
는 Servlet 기반 web application을 테스트할 때 Spring REST Docs를 사용하도록 MockMvc
bean을 customize합니다.
다음 예제와 같이 @Autowired
를 사용하여 inject하고 Mock MVC와 Spring REST Docs를 사용할 때 처럼 테스트에 사용할 수 있습니다:
@WebMvcTest(UserController.class)
@AutoConfigureRestDocs
class UserDocumentationTests {
@Autowired
private MockMvc mvc;
@Test
void listUsers() throws Exception {
this.mvc.perform(get("/users").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andDo(document("list-users"));
}
}
@AutoConfigureRestDocs
의 attribute에서 제공하는 것보다 Spring REST Docs 구성에 대한 더 많은 제어가 필요한 경우 다음 예와 같이 RestDocsMockMvcConfigurationCustomizer
bean을 사용할 수 있습니다:
@TestConfiguration
static class CustomizationConfiguration
implements RestDocsMockMvcConfigurationCustomizer {
@Override
public void customize(MockMvcRestDocumentationConfigurer configurer) {
configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
}
}
parameterized output directory에 Spring REST Docs 지원을 사용하려면 RestDocumentationResultHandler
bean을 생성할 수 있습니다.
auto-configuration은 이 result handler로 alwaysDo
을 호출하여 각 MockMvc
호출을 자동으로 기본 snippet을 생성하게 합니다.
아래 예제는 RestDocumentationResultHandler
가 정의듸는 것을 보여줍니다:
@TestConfiguration(proxyBeanMethods = false)
static class ResultHandlerConfiguration {
@Bean
public RestDocumentationResultHandler restDocumentation() {
return MockMvcRestDocumentation.document("{method-name}");
}
}
Auto-configured Spring REST Docs Tests with WebTestClient
@AutoConfigureRestDocs
는 reactive web application을 테스트할 때 WebTestClient
와 함께 사용할 수 있습니다.
다음 예제와 같이 @Autowired
를 사용하여 inject하고 @WebFluxTest
및 Spring REST Docs를 사용할 때처럼 테스트에 사용할 수 있습니다:
@WebFluxTest
@AutoConfigureRestDocs
class UsersDocumentationTests {
@Autowired
private WebTestClient webTestClient;
@Test
void listUsers() {
this.webTestClient
.get().uri("/")
.exchange()
.expectStatus()
.isOk()
.expectBody()
.consumeWith(document("list-users"));
}
}
@AutoConfigureRestDocs
의 attribute에서 제공하는 것보다 Spring REST Docs 구성에 대한 더 많은 제어가 필요한 경우 다음 예와 같이 RestDocsWebTestClientConfigurationCustomizer
bean을 사용할 수 있습니다:
@TestConfiguration(proxyBeanMethods = false)
public class AdvancedRestDocsConfiguration implements RestDocsWebTestClientConfigurationCustomizer {
@Override
public void customize(WebTestClientRestDocumentationConfigurer configurer) {
configurer.snippets().withEncoding("UTF-8");
}
}
Auto-configured Spring REST Docs Tests with REST Assured
@AutoConfigureRestDocs
은 Spring REST Docs를 사용하도록 사전 구성된 RequestSpecification
bean을 테스트에서 사용할 수 있도록 합니다.
다음 예제와 같이 @Autowired
를 사용하여 inject하고 REST Assured 및 Spring REST Docs를 사용할 때처럼 테스트에 사용할 수 있습니다:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureRestDocs
class UserDocumentationTests {
@Test
void listUsers(@Autowired RequestSpecification documentationSpec, @LocalServerPort int port) {
given(documentationSpec)
.filter(document("list-users"))
.when()
.port(port)
.get("/")
.then().assertThat()
.statusCode(is(200));
}
}
@AutoConfigureRestDocs
의 attribute에서 제공하는 것보다 Spring REST Docs 구성에 대한 더 많은 제어가 필요한 경우 다음 예와 같이 RestDocsRestAssuredConfigurationCustomizer
bean을 사용할 수
@TestConfiguration(proxyBeanMethods = false)
public class AdvancedRestDocsConfiguration implements RestDocsRestAssuredConfigurationCustomizer {
@Override
public void customize(RestAssuredRestDocumentationConfigurer configurer) {
configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
}
}
2.3.26. Auto-configured Spring Web Services Tests
@WebServiceClientTest
를 사용하여 Spring Web Service project를 사용하여 call web service를 사용하는 application을 테스트할 수 있습니다.
기본적으로 mock WebServiceServer
bean을 구성하고 WebServiceTemplateBuilder
를 자동으로 customize 합니다.
(Spring Boot에서 Web Service를 사용하는 방법에 대한 자세한 내용은 선행 챕터의 "[boot-features-webservices]" 를 참조하세요.)
@WebServiceClientTest 로 활성화된 auto-configuration 목록은 부록(appendix)에서 확인할 수 있습니다.
|
다음 예제는 @WebServiceClientTest
annotation을 사용하는 경우를 보여줍니다:
@WebServiceClientTest(ExampleWebServiceClient.class)
class WebServiceClientIntegrationTests {
@Autowired
private MockWebServiceServer server;
@Autowired
private ExampleWebServiceClient client;
@Test
void mockServerCall() {
this.server.expect(payload(new StringSource("<request/>"))).andRespond(
withPayload(new StringSource("<response><status>200</status></response>")));
assertThat(this.client.test()).extracting(Response::getStatus).isEqualTo(200);
}
}
2.3.27. Additional Auto-configuration and Slicing
각 slice는 slice의 일부로 포함되어야 하는 auto-configuration을 정의하는 하나 이상의 @AutoConfigure…
annotation을 제공합니다.
custom @AutoConfigure…
annotation을 생성하거나 다음 예와 같이 @ImportAutoConfiguration
을 테스트에 추가하여 테스트 별로 추가 auto-configuration을 추가할 수 있습니다:
@JdbcTest
@ImportAutoConfiguration(IntegrationAutoConfiguration.class)
class ExampleJdbcTests {
}
auto-configuration은 Spring Boot에서 특정 방식으로 처리되므로 일반 @Import annotation을 사용하여 import 하지 마세요.
|
Alternatively, additional auto-configurations can be added for any use of a slice annotation by registering them in META-INF/spring.factories
as shown in the following example:
org.springframework.boot.test.autoconfigure.jdbc.JdbcTest=com.example.IntegrationAutoConfiguration
@ImportAutoConfiguration 으로 meta-annotation이 있기만 하면 slice 또는 @AutoConfigure… annotation을 이 방법으로 customize 할 수 있습니다.
|
2.3.28. User Configuration and Slicing
그런 다음 application의 main class를 기능의 특정 영역에 특정한 구성 성질으로 흩어지지 않게 하는 것이 중요해집니다.
Spring Batch를 사용하고 있으며 auto-configuration에 의존한다고 가정해보세요.
@SpringBootApplication
을 다음과 같이 정의할 수 있습니다:
@SpringBootApplication
@EnableBatchProcessing
public class SampleApplication { ... }
이 class는 테스트를 위한 source configuration이기 때문에 모든 slice 테스트는 실제로 Spring Batch를 시작하려고 시도합니다. 이는 확실히 원하는 작업이 아닙니다.
다음 예제와 같이 해당 영역별 구성을 application과 동일한 수준의 별도 @Configuration
class로 이동하는 것이 좋습니다:
@Configuration(proxyBeanMethods = false)
@EnableBatchProcessing
public class BatchConfiguration { ... }
application의 복잡도에 따라 사용자 지정을 위한 단일 @Configuration class 또는 domain 영역 당 하나의 class를 가질 수 있습니다.
후자의 접근 방식을 사용하면 필요한 경우 @Import annotation을 사용하여 테스트 중 하나에서 활성화 할 수 있습니다.
|
테스트 slice는 scann으로 부터 @Configuration
class를 제외합니다.
예를 들어 @WebMvcTest
의 경우 다음 구성은 test slice에서 로드된 application context에 지정된 WebMvcConfigurer
bean을 포함하지 않습니다:
@Configuration
public class WebConfiguration {
@Bean
public WebMvcConfigurer testConfigurer() {
return new WebMvcConfigurer() {
...
};
}
}
그러나 아래 구성에서는 test slice에 의해 custom WebMvcConfigurer
가 로드됩니다.
@Component
public class TestWebMvcConfigurer implements WebMvcConfigurer {
...
}
또 다른 혼란의 원인은 classpath scan입니다. 합리적인 방식으로 code를 구성하는 동안 추가 package를 scan해야 한다고 가정합니다. application은 다음 코드와 유사 할 수 있습니다:
@SpringBootApplication
@ComponentScan({ "com.example.app", "org.acme.another" })
public class SampleApplication { ... }
이렇게 하면 선택한 slice에 관계 없이 두 package를 scan 하는 부작용이 있는 기본 component scan directive(지시문)이 효과적으로 재정의 됩니다.
예를 들어 @DataJpaTest
는 갑자기 application의 component와 user configuration을 scan하는 것처럼 보입니다.
다시 말하면, custom directive를 별도의 class로 이동하는 것이 이 문제를 해결하는 좋은 방법입니다.
이 옵션이 선택 사항이 아닌 경우 테스트 계층 아딘가에 @SpringBootConfiguration 을 생성하여 대신 사용할 수 있습니다.
또는 테스트 source를 지정하여 default source를 찾는 동작을 비활성화 할 수 있습니다.
|
2.3.29. Using Spock to Test Spring Boot Applications
Spock을 사용하여 Spring Boot application을 테스트하려면 Spock의 spock-spring
module에 대한 dependency를 application buill에 추가해야합니다.
spock-spring
은 Spring의 test framework를 Spock에 통합합니다.
자세한 내용은 Spock의 Spring module을 위한 문서 를 참조하세요.
Spring Boot 2.5.x 및 Groovy 3.x 지원 시 spock을 사용할 수 있는 두가지 option이 있습니다: 최신 Spock 2.0 milestone 이나 Groovy 3.x와 호환되는 release를 사용하거나 Spock 1.3과 함께 사용하고 Spring Boot의 Groovy 버전을 2.5.x로 downgrade 합니다. |
2.4. Test Utilities
application을 테스트 할 때 일반적으로 유용한 몇가지 test utility class가 spring-boot
의 일부로 packaging 됩니다.
2.4.1. ConfigFileApplicationContextInitializer
ConfigFileApplicationContextInitializer
은 Spring Boot application.properties
file을 로드하는 테스트에 적용할 수 있는 ApplicationContextInitializer
입니다.
다음 예제와 같이 @SpringBootTest
에서 제공하는 기능의 full set이 필요하지 않을 때 사용할 수 있습니다:
@ContextConfiguration(classes = Config.class,
initializers = ConfigFileApplicationContextInitializer.class)
ConfigFileApplicationContextInitializer 을 단독으로 사용하는 것은 @Value("${…}") inject를 제공하지 않습니다.
Spring의 Environment 에 application.properties file이 로드되도록 하는 것만이 유일한 작업입니다.
@Value 지원을 받으려면 PropertySourcesPlaceholderConfigurer 를 추가로 구성하거나 @SpringBootTest 를 사용해야 auto-configure가 됩니다.
|
2.4.2. TestPropertyValues
TestPropertyValues
는 ConfigurableEnvironment
또는 ConfigurableApplicationContext
에 property를 빠르게 추가할 수 있도록 합니다.
다음과 같이 key=value
문자열을 사용하여 호출할 수 있습니다:
TestPropertyValues.of("org=Spring", "name=Boot").applyTo(env);
2.4.3. OutputCapture
OutputCapture
는 System.out
과 System.err
output을 캡처하는데 사용할 수 있는 JUnit Extension
입니다.
사용하려면 다음 예제와 같이 @ExtendWith(OutputCaptureExtension.class)
를 추가하고 CapturedOutput
을 argument로 test class constructor나 test method에 inject합니다:
@ExtendWith(OutputCaptureExtension.class)
class OutputCaptureTests {
@Test
void testName(CapturedOutput output) {
System.out.println("Hello World!");
assertThat(output).contains("World");
}
}
2.4.4. TestRestTemplate
TestRestTemplate
은 Spring의 RestTemplate
을 편하게 대체하여 통합 테스트에 유용합니다.
vanilla template 또는 Basic HTTP authentication을 보내는 template(사용자 이름 및 암호 포함)을 얻을 수 있습니다.
두 경우 모두 template은 server-side error에 exception을 throw하지 않고 테스트하기 쉬운 방식으로 작동합니다.
Spring Framework 5.0은 WebFlux 통합 테스트와 WebFlux 및 MVC end-to-end 테스트에 모두 적합한 새로운 WebTestClient 를 제공합니다.
TestRestTemplate 과 달리 assertion에 뛰어난 API를 제공합니다.
|
Apache HTTP client(version 4.3.2 이상)를 사용하는 것이 좋습니다.
classpath에 해당 항목이 있는 경우 TestRestTemplate
는 client를 적절하게 구성하여 응답합니다.
Apache의 HTTP client를 사용하는 경우 테스트하기 쉬운 일부 추가 기능이 사용되도록 설정됩니다:
-
redirect가 수행되지 않으므로 response location을 assert 할 수 있습니다.
-
cookie가 무시되므로 template은 stateless 입니다.
TestRestTemplate
은 다음 예제와 같이 통합 테스트에서 직접 인스턴스화 할 수 있습니다:
public class MyTest {
private TestRestTemplate template = new TestRestTemplate();
@Test
public void testRequest() throws Exception {
HttpHeaders headers = this.template.getForEntity(
"https://myhost.example.com/example", String.class).getHeaders();
assertThat(headers.getLocation()).hasHost("other.example.com");
}
}
또는 @SpringBootTest
annotation을 사용하는 경우 WebEnvironment.RANDOM_PORT
또는 WebEnvironment.DEFINED_PORT
로 완전히 설정된 TestRestTemplate
를 inject하고 사용할 수 있습니다.
필요한 경우 RestTemplateBuilder
bean을 통해 추가 customize를 할 수 있습니다.
host 및 port를 지정하지 않은 URL은 다음 예제와 같이 embedded server에 자동으로 연결됩니다:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class SampleWebClientTests {
@Autowired
private TestRestTemplate template;
@Test
void testRequest() {
HttpHeaders headers = this.template.getForEntity("/example", String.class).getHeaders();
assertThat(headers.getLocation()).hasHost("other.example.com");
}
@TestConfiguration(proxyBeanMethods = false)
static class RestTemplateBuilderConfiguration {
@Bean
RestTemplateBuilder restTemplateBuilder() {
return new RestTemplateBuilder().setConnectTimeout(Duration.ofSeconds(1))
.setReadTimeout(Duration.ofSeconds(1));
}
}
}