Java 如何在参数化的情况下运行JUnit SpringJUnit4 ClassRunner?
由于重复的Java 如何在参数化的情况下运行JUnit SpringJUnit4 ClassRunner?,java,spring,junit,spring-test,Java,Spring,Junit,Spring Test,由于重复的@RunWith注释,以下代码无效: @RunWith(SpringJUnit4ClassRunner.class) @RunWith(Parameterized.class) @SpringApplicationConfiguration(classes = {ApplicationConfigTest.class}) public class ServiceTest { } 但是如何将这两种注释结合使用呢?至少有两种方法可以做到这一点: 跟随 您的测试需要如下所示: @RunW
@RunWith
注释,以下代码无效:
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(Parameterized.class)
@SpringApplicationConfiguration(classes = {ApplicationConfigTest.class})
public class ServiceTest {
}
但是如何将这两种注释结合使用呢?至少有两种方法可以做到这一点:
@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);
}
...
}
@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();
...
JUnit4.12还有另一个解决方案,不需要Spring4.2+ JUnit 4.12引入了允许将参数化测试和Spring注入相结合的功能
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;
}
};
}
}
工厂可以添加到测试类中,以提供完整的弹簧支持,如和
如果您需要静态方法中的Spring上下文来提供测试实例的参数,请在这里查看我的答案。自己处理应用程序上下文
对我有效的是有一个@RunWith(Parameterized.class)
测试类,“手动”管理应用程序上下文
为此,我使用@ContextConfiguration
中的相同字符串集合创建了一个应用程序上下文。因此,与其
@ContextConfiguration(locations = { "classpath:spring-config-file1.xml",
"classpath:spring-config-file2.xml" })
我有
对于我需要的每个@Autowired,我都是从创建的上下文中手工获取的:
SomeClass someBean = ctx.getBean("someClassAutowiredBean", SomeClass.class);
不要忘记在结尾处关闭上下文:
((ClassPathXmlApplicationContext) ctx).close();
这是另一个最新的解决方案,非常好,使用第一种方法,您只需在组件上使用
@Autowired
,即可正确注入。另外,我可以使用@SpringApplicationConfiguration
而不是@ContextConfiguration
,它工作得很好,不确定区别是什么…您的第一个链接似乎已失效:-(@mavarazy我尝试了第一个解决方案:工作!非常感谢。@keyoxy是否可以并行运行所有测试?
SomeClass someBean = ctx.getBean("someClassAutowiredBean", SomeClass.class);
((ClassPathXmlApplicationContext) ctx).close();