Junit 테스트 클래스 전체에서 스프링 애플리케이션 컨텍스트 재사용
JUnit 테스트 케이스(통합 테스트)가 다수 있으며 논리적으로 여러 테스트 클래스로 분류되어 있습니다.
테스트 클래스당 1회 Spring 어플리케이션 컨텍스트를 로드하여 http://static.springsource.org/spring/docs/current/spring-framework-reference/html/testing.html에서 설명한 바와 같이 JUnit 테스트클래스의 모든 테스트 케이스에 재사용할 수 있습니다.
단, JUnit 테스트 클래스에서는 Spring 어플리케이션 콘텍스트를 한 번만 로드할 수 있는 방법이 있는지 궁금합니다.
WWIW는 Spring 3.0.5, JUnit 4.5를 사용하고 Maven을 사용하여 프로젝트를 구축합니다.
네, 이건 완벽하게 가능합니다.당신이 해야 할 일은 같은 것을 사용하는 것이다.locations
테스트 클래스의 속성:
@ContextConfiguration(locations = "classpath:test-context.xml")
Spring은 응용 프로그램콘텍스트를 캐시합니다locations
같은 경우로 간주합니다.locations
는 두 번째로 표시됩니다.스프링에서는 새로운 콘텍스트를 작성하는 것이 아니라 같은 콘텍스트를 사용합니다.
저는 이 기능에 대한 기사를 썼습니다: Speeding up Spring Integration tests.또, Spring 메뉴얼 「9.3.2.1 컨텍스트 관리 및 캐싱」에도 자세하게 설명되어 있습니다.
이것은 흥미로운 의미를 내포하고 있다.스프링은 JUnit이 언제 완료되었는지 알 수 없으므로 모든 컨텍스트를 영원히 캐시하고 JVM 셧다운 후크를 사용하여 닫습니다.이 동작(특히 다른 테스트클래스가 많은 경우)locations
)는, 메모리 사용량의 과다나 메모리 누수등의 원인이 될 가능성이 있습니다.콘텍스트 캐싱의 또 다른 장점입니다.
봄 3.2.2 시점의 Tomasz Nurkiewicz의 답변에 추가한다.@ContextHierarchy
주석을 사용하여 연결된 개별 다중 컨텍스트 구조를 가질 수 있습니다.이는 여러 테스트클래스가 메모리 내 데이터베이스 셋업(예를 들어 datasource, Entity Manager Factory, tx manager 등)을 공유하는 경우에 도움이 됩니다.
예를 들어 다음과 같습니다.
@ContextHierarchy({
@ContextConfiguration("/test-db-setup-context.xml"),
@ContextConfiguration("FirstTest-context.xml")
})
@RunWith(SpringJUnit4ClassRunner.class)
public class FirstTest {
...
}
@ContextHierarchy({
@ContextConfiguration("/test-db-setup-context.xml"),
@ContextConfiguration("SecondTest-context.xml")
})
@RunWith(SpringJUnit4ClassRunner.class)
public class SecondTest {
...
}
이 셋업에 의해 "test-db-setup-context.xml"을 사용하는 컨텍스트는 1회만 작성되지만 그 안에 있는 콩은 개별 유닛 테스트의 컨텍스트에 삽입할 수 있습니다.
매뉴얼에 대한 자세한 내용은http://http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html#testcontext-ctx-management 를 참조해 주세요.
한 가지 주목할 점은 @SpringBoot을 사용할 경우Tests but 다시 말하지만 Spring은 모든 테스트에 응용 프로그램콘텍스트를 재사용할 방법이 없습니다.
해결 방법 및 해결 방법.
@SpringBootTests(webEnvironment = WebEnvironment.RANDOM_PORT, classes = Application.class)
public abstract class AbstractIT {
@MockBean
private ProductService productService;
@MockBean
private InvoiceService invoiceService;
}
그러면 테스트 클래스는 다음과 같이 볼 수 있습니다.
public class ProductControllerIT extends AbstractIT {
// please don't use @MockBean here
@Test
public void searchProduct_ShouldSuccess() {
}
}
public class InvoiceControllerIT extends AbstractIT {
// please don't use @MockBean here
@Test
public void searchInvoice_ShouldSuccess() {
}
}
기본적으로 다른 테스트클래스에서 동일한 애플리케이션콘텍스트 설정을 사용하고 있는 경우, 이 설정을 실시할 수 있는 것은 스프링으로 충분합니다.예를 들어 다음과 같은 2개의 클래스A와 B가 있다고 합니다.
@ActiveProfiles("h2")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class A {
@MockBean
private C c;
//Autowired fields, test cases etc...
}
@ActiveProfiles("h2")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class B {
@MockBean
private D d;
//Autowired fields, test cases etc...
}
이 예에서는 클래스 A는 콩 C를, 클래스 B는 콩 D를 모킹합니다.따라서 스프링은 이러한 설정을 2개의 다른 설정으로 간주하기 때문에 어플리케이션콘텍스트는 클래스A용으로 1회, 클래스B용으로 1회 로드됩니다.
이 두 클래스 간에 애플리케이션 컨텍스트를 스프링이 공유하도록 하려면 다음과 같이 해야 합니다.
@ActiveProfiles("h2")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class A {
@MockBean
private C c;
@MockBean
private D d;
//Autowired fields, test cases etc...
}
@ActiveProfiles("h2")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class B {
@MockBean
private C c;
@MockBean
private D d;
//Autowired fields, test cases etc...
}
이와 같이 클래스를 배선하면 테스트 스위트에서 먼저 실행되는 클래스에 따라 클래스 A 또는 클래스B 중 하나에 대해 응용 프로그램콘텍스트가 1회만 로딩됩니다.이 클래스는 여러 테스트클래스에 걸쳐 복제할 수 있지만 테스트클래스를 다르게 커스터마이즈할 수 없습니다.테스트 클래스가 다른 클래스와 다른 커스터마이즈(스프링의 관점에서)는, 봄까지 다른 애플리케이션 콘텍스트를 작성하게 됩니다.
다음과 같은 구성 클래스를 만듭니다.
@ActiveProfiles("local")
@RunWith(SpringJUnit4ClassRunner.class )
@SpringBootTest(classes ={add your spring beans configuration classess})
@TestPropertySource(properties = {"spring.config.location=classpath:application"})
@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class)
public class RunConfigration {
private ClassLoader classloader = Thread.currentThread().getContextClassLoader();
private static final Logger LOG = LoggerFactory.getLogger(S2BXISINServiceTest.class);
//auto wire all the beans you wanted to use in your test classes
@Autowired
public XYZ xyz;
@Autowired
public ABC abc;
}
Create your test suite like below
@RunWith(Suite.class)
@Suite.SuiteClasses({Test1.class,test2.class})
public class TestSuite extends RunConfigration {
private ClassLoader classloader = Thread.currentThread().getContextClassLoader();
private static final Logger LOG = LoggerFactory.getLogger(TestSuite.class);
}
다음과 같은 테스트 클래스를 만듭니다.
public class Test1 extends RunConfigration {
@Test
public void test1()
{
you can use autowired beans of RunConfigration classes here
}
}
public class Test2a extends RunConfigration {
@Test
public void test2()
{
you can use autowired beans of RunConfigration classes here
}
}
언급URL : https://stackoverflow.com/questions/8501975/reuse-spring-application-context-across-junit-test-classes
'source' 카테고리의 다른 글
d3 js - http get을 사용하지 않고 json을 로드합니다. (0) | 2023.03.25 |
---|---|
반응 오류:스타일 프롭 값은 개체 반응/스타일 프롭 개체여야 합니다. (0) | 2023.03.25 |
ReactJs - 새로운 useStateRespect 후크의 preState? (0) | 2023.03.25 |
Wordpress에서 사용자 지정 페이지 표시 Permalink를 만드는 방법 (0) | 2023.03.25 |
AngularJs가 컨트롤러($scope)의 양식 개체에 액세스할 수 없습니다. (0) | 2023.03.25 |