5.6. Context Management ~ 5.8. Testing Request- and Session-scoped Beans
틀린 해석이나 내용이 있다면 알려주세요 🤨
5.6. Context Management
각 TestContext 는 담당 test instance에 대한 context management 및 캐싱지원을 제공한다
test instance는 구성된 ApplicationContext에 대한 액세스 권한을 자동으로 받지 않는다
그러나 테스트 클래스가 ApplicationContextAware interface를 구현하는 경우 ApplicationContext에 대한 참조가 test instance에제공된다
AbstractJUnit4SpringContextTests 및 AbstractTestNGSpringContextTests는 ApplicationContextAware를 구현하므로 ApplicationContext에 대한 액세스를 자동으로 제공한다
@Autowired ApplicationContext
As an alternative to implementing the ApplicationContextAware interface, you can inject the application context for your test class through the @Autowired annotation on either a field or setter method, as the following example shows:
@SpringJUnitConfig
class MyTest {
@Autowired
ApplicationContext applicationContext;
// class body...
}
@Autowired를 통한 ApplicationContext 주입
@SpringJUnitWebConfig
class MyWebAppTest {
@Autowired
WebApplicationContext wac;
// class body...
}
@ContextConfiguration 클래스 수준에서 주석을 선언하여 구성을 수행하면 된다
테스트 클래스가 명시적 선언을 하지 않은 경우에도 구성된 ContextLoader가 기본 구성 클래스에서 Context load 방법을 결정한다
In addition to context resource locations and component classes, an application context can also be configured through application context initializers.
구성방법들에 대한 내용은 링크로
- Context Configuration with XML resources
- Context Configuration with Groovy Scripts
- Context Configuration with Component Classes
- Mixing XML, Groovy Scripts, and Component Classes
- Context Configuration with Context Initializers
- Context Configuration Inheritance
- Context Configuration with Environment Profiles
- Context Configuration with Test Property Sources
- Context Configuration with Dynamic Property Sources
- Loading a WebApplicationContext
- Context Caching
- Context Hierarchies
5.7. Dependency Injection of Test Fixtures
DependencyInjectionTestExecutionListener(기본구성)를 사용하면 @ContextConfiguration 또는 관련 주석으로 구성한 애플리케이션 컨텍스트의 Bean에서 테스트 인스턴스의 종속성이 주입된다
어떤 주석을 선택하고 주석을 세터 메소드에 배치하는지 필드에 배치하는지에 따라 세터 주입, 필드 주입 또는 둘 모두를 사용할 수 있다
JUnit Jupiter를 사용하는 경우 선택적으로 생성자 주입을 사용할 수 있다(SpringExtension을 사용한 종속성 주입)
Spring의 주석 기반 주입 지원과의 일관성을 위해 필드 및 세터 주입을 위해
Spring의 @Autowired 주석 또는 JSR-330의 @Inject 주석을 사용할 수도 있다.
Unit Jupiter 이외의 테스트 프레임워크의 경우 TestContext 프레임워크는 테스트 클래스의 인스턴스화되지 않는다
생성자에 @Autowired 또는 @Inject를 사용은 테스트 클래스에 영향받지 않는다.
@Autowired는 유형별로 autowiring을 수행하는 데 사용되기 때문에 동일한 유형의 여러 bean 정의가 있는 경우 해당 특정 bean 접근 방식을 사용할 수 없다.
이때 @Qualifier와 함께 @Autowired를 사용하면 된다.
@Named와 함께 @Inject를 사용하도록 선택할 수 있다. 또는 테스트 클래스가 ApplicationContext에 액세스할 수 있는 경우 applicationContext.getBean 을 사용하면 되는데
applicationContext.getBean("titleRepository", TitleRepository.class) 이런 식으로 호출 하여 명시적 조회를 수행할 수 있다
Test instance 에 DI 를 적용하지않으려면 @Autowired 또는 @Inject 애노테이션을 붙이지 말아야한다
아니면 @ㅅTestExecutionListeners 에서 클래스를 명시적으로 구성 하고 리스너 목록에서 DependencyInjectionTestExecutionListener.class를 생략하면 종속성 주입을 완전히 비활성화할 수 있다
Consider the scenario of testing a HibernateTitleRepository class, as outlined in the Goals section.
@Autowired필드 주입(JUnit Jupiter 기반)
@ExtendWith(SpringExtension.class)
// specifies the Spring configuration to load for this test fixture
@ContextConfiguration("repository-config.xml")
class HibernateTitleRepositoryTests {
// this instance will be dependency injected by type
@Autowired
HibernateTitleRepository titleRepository;
@Test
void findById() {
Title title = titleRepository.findById(new Long(10));
assertNotNull(title);
}
}
또는 setter insert 시에 구성
@ExtendWith(SpringExtension.class)
// specifies the Spring configuration to load for this test fixture
@ContextConfiguration("repository-config.xml")
class HibernateTitleRepositoryTests {
// this instance will be dependency injected by type
HibernateTitleRepository titleRepository;
@Autowired
void setTitleRepository(HibernateTitleRepository titleRepository) {
this.titleRepository = titleRepository;
}
@Test
void findById() {
Title title = titleRepository.findById(new Long(10));
assertNotNull(title);
}
}
use the same XML context file referenced by the @ContextConfiguration annotation (that is, repository-config.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- this bean will be injected into the HibernateTitleRepositoryTests class -->
<bean id="titleRepository" class="com.foo.repository.hibernate.HibernateTitleRepository">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- configuration elided for brevity -->
</bean>
</beans>
setter 메소드 중 하나에서 @Autowired 를 사용하는 기본 클래스에서 확장하려는 경우에 DataSource bean인 경우 여러 bean이 있을 수 있다
이럴때 setter method를 재정의 하고, @Qualifier 애노테이션을 붙여 특정 대상 빈만 나타낼 수 있다
@Autowired
@Override
public void setDataSource(@Qualifier("myDataSource") DataSource dataSource) {
super.setDataSource(dataSource);
}
5.8. Testing Request- and Session-scoped Beans
Request- and session-scoped beans
요청 범위 및 세션 범위 bean 테스트 또한 가능하다
- Ensure that a WebApplicationContext is loaded for your test by annotating your test class with @WebAppConfiguration.
- Inject the mock request or session into your test instance and prepare your test fixture as appropriate.
- Invoke your web component that you retrieved from the configured WebApplicationContext (with dependency injection).
- Perform assertions against the mocks.
Request-scoped bean configuration
<beans>
<bean id="userService" class="com.example.SimpleUserService"
c:loginAction-ref="loginAction"/>
<bean id="loginAction" class="com.example.LoginAction"
c:username="#{request.getParameter('user')}"
c:password="#{request.getParameter('pswd')}"
scope="request">
<aop:scoped-proxy/>
</bean>
</beans>
userService bean은 session 범위의 userPreferences bean에 종속된다
UserPreferences bean은 http session에서 인스턴스화 되기 때문에
이를 모의 구성 해주어야 한다
@SpringJUnitWebConfig
class RequestScopedBeanTests {
@Autowired UserService userService;
@Autowired MockHttpServletRequest request;
@Test
void requestScope() {
request.setParameter("user", "enigma");
request.setParameter("pswd", "$pr!ng");
LoginResults results = userService.loginUser();
// assert results
}
}
Session-scoped bean configuration
<beans>
<bean id="userService" class="com.example.SimpleUserService"
c:userPreferences-ref="userPreferences" />
<bean id="userPreferences" class="com.example.UserPreferences"
c:theme="#{session.getAttribute('theme')}"
scope="session">
<aop:scoped-proxy/>
</bean>
</beans>
SessionScopedBeanTests에서 UserService와 MockHttpSession을 테스트 인스턴스에 주입한다.
sessionScope() 테스트 메서드 내에서 제공된 MockHttpSession에서 예상 테마 속성을 설정하여 테스트 fixture를 설정한다. userService에서 processUserPreferences() 메서드가 호출되면 사용자 서비스가 현재 MockHttpSession에 대한 세션 범위의 userPreferences에 액세스할 수 있고 구성된 테마를 기반으로 결과에 대해 assertions를 수행할 수 있다.
@SpringJUnitWebConfig
class SessionScopedBeanTests {
@Autowired UserService userService;
@Autowired MockHttpSession session;
@Test
void sessionScope() throws Exception {
session.setAttribute("theme", "blue");
Results results = userService.processUserPreferences();
// assert results
}
}
'Web > spring' 카테고리의 다른 글
[Spring framework Web MVC docs] 1.12. MVC Config (0) | 2023.02.11 |
---|---|
[Spring framework Web MVC docs] 1.1.6.Path Matching ~ 1.1.7. Interception (0) | 2023.02.10 |
[Spring framework testing] 5. Spring TestContext Framework (1) (0) | 2023.02.09 |
[Spring security] Architecture (0) | 2023.02.08 |
[Spring framework Web MVC docs] 1.1.1.Context Hierarchy ~ 1.1.5. Processing (0) | 2023.02.08 |