Parametrized로 JUnit SpringJUnit4ClassRunner를 실행하는 방법은 무엇입니까?
다음 코드는 중복 된 @RunWith
주석 으로 인해 유효하지 않습니다 .
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(Parameterized.class)
@SpringApplicationConfiguration(classes = {ApplicationConfigTest.class})
public class ServiceTest {
}
하지만이 두 주석을 어떻게 함께 사용할 수 있습니까?
이를 수행하기위한 최소 2 가지 옵션이 있습니다.
-
테스트는 다음과 같아야합니다.
@RunWith(Parameterized.class) @ContextConfiguration(classes = {ApplicationConfigTest.class}) public class ServiceTest { private TestContextManager testContextManager; @Before public void setUpContext() throws Exception { //this is where the magic happens, we actually do "by hand" what the spring runner would do for us, // read the JavaDoc for the class bellow to know exactly what it does, the method names are quite accurate though this.testContextManager = new TestContextManager(getClass()); this.testContextManager.prepareTestInstance(this); } ... }
이전 블로그를 기반으로하지만 일반화 된 방식으로 지원을 추가 하는 github 프로젝트 https://github.com/mmichaelis/spring-aware-rule 이 있습니다.
@SuppressWarnings("InstanceMethodNamingConvention") @ContextConfiguration(classes = {ServiceTest.class}) public class SpringAwareTest { @ClassRule public static final SpringAware SPRING_AWARE = SpringAware.forClass(SpringAwareTest.class); @Rule public TestRule springAwareMethod = SPRING_AWARE.forInstance(this); @Rule public TestName testName = new TestName(); ... }
따라서 접근 방식 중 하나를 구현하는 기본 클래스와이를 상속하는 모든 테스트를 가질 수 있습니다.
Spring에서 제공하는 SpringClassRule 및 SpringMethodRule을 사용할 수 있습니다.
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.springframework.test.context.junit4.rules.SpringClassRule;
import org.springframework.test.context.junit4.rules.SpringMethodRule;
@RunWith(Parameterized.class)
@ContextConfiguration(...)
public class MyTest {
@ClassRule
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
...
Spring 4.2+가 필요없는 JUnit 4.12의 또 다른 솔루션이 있습니다.
JUnit 4.12 introduces ParametersRunnerFactory which allow to combine parameterized test and Spring injection.
public class SpringParametersRunnerFactory implements ParametersRunnerFactory {
@Override
public Runner createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError {
final BlockJUnit4ClassRunnerWithParameters runnerWithParameters = new BlockJUnit4ClassRunnerWithParameters(test);
return new SpringJUnit4ClassRunner(test.getTestClass().getJavaClass()) {
@Override
protected Object createTest() throws Exception {
final Object testInstance = runnerWithParameters.createTest();
getTestContextManager().prepareTestInstance(testInstance);
return testInstance;
}
};
}
}
The factory can be added to test class to give full Spring support like test transaction, reinit dirty context and servlet test.
@UseParametersRunnerFactory(SpringParametersRunnerFactory.class)
@RunWith(Parameterized.class)
@ContextConfiguration(locations = {"/test-context.xml", "/mvc-context.xml"})
@WebAppConfiguration
@Transactional
@TransactionConfiguration
public class MyTransactionalTest {
@Autowired
private WebApplicationContext context;
...
}
If you need Spring context inside @Parameters static method to provide parameters to test instances, please see my answer here How can I use the Parameterized JUnit test runner with a field that's injected using Spring?.
Handle application context by yourself
What worked for me was having a @RunWith(Parameterized.class)
test class that managed the application context "by hand".
To do that I created an application context with the same string collection that would be in the @ContextConfiguration
. So instead of having
@ContextConfiguration(locations = { "classpath:spring-config-file1.xml",
"classpath:spring-config-file2.xml" })
I had
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] {
"classpath:spring-config-file1.xml", "classpath:spring-config-file2.xml" });
And for each @Autowired I needed I fetched it by hand from the created context:
SomeClass someBean = ctx.getBean("someClassAutowiredBean", SomeClass.class);
Do not forget to close the context at the end:
((ClassPathXmlApplicationContext) ctx).close();
'developer tip' 카테고리의 다른 글
Javascript를 통해 쿠키를 HttpOnly로 설정 (0) | 2020.11.24 |
---|---|
이 Android SDK에는 ADT 버전 23.0.0 이상이 필요합니다. (0) | 2020.11.24 |
ASP.NET Core에서 ConfigureServices 내 인스턴스를 확인하는 방법 (0) | 2020.11.24 |
Python 2.5에서 사용할 수있는 JSON 모듈은 무엇입니까? (0) | 2020.11.24 |
WHERE col IN (…) 조건에 대한 제한 (0) | 2020.11.24 |