有没有办法让一个扩展AbstractTransactionalJUnit4SpringContexts的类与JUnit自己的@RunWith(Parameterized.class)很好地配合,以便标记为Autowired的字段能够正确连接?
@RunWith(Parameterized.class)
public class Foo extends AbstractTransactionalJUnit4SpringContextTests {
@Autowired private Bar bar
@Parameters public static Collection<Object[]> data() {
// return parameters, following pattern in
// http://junit.org/apidocs/org/junit/runners/Parameterized.html
}
@Test public void someTest(){
bar.baz() //NullPointerException
}
}
答案 0 :(得分:5)
答案 1 :(得分:4)
您可以使用Spring的TestContextManager。在这个例子中,我使用Theories而不是Parameterized。
@RunWith(Theories.class)
@ContextConfiguration(locations = "classpath:/spring-context.xml")
public class SeleniumCase {
@DataPoints
public static WebDriver[] drivers() {
return new WebDriver[] { firefoxDriver, internetExplorerDriver };
}
private TestContextManager testContextManager;
@Autowired
SomethingDao dao;
private static FirefoxDriver firefoxDriver = new FirefoxDriver();
private static InternetExplorerDriver internetExplorerDriver = new InternetExplorerDriver();
@AfterClass
public static void tearDown() {
firefoxDriver.close();
internetExplorerDriver.close();
}
@Before
public void setUpStringContext() throws Exception {
testContextManager = new TestContextManager(getClass());
testContextManager.prepareTestInstance(this);
}
@Theory
public void testWork(WebDriver driver) {
assertNotNull(driver);
assertNotNull(dao);
}
}
我在这里找到了这个解决方案:How to do Parameterized/Theories tests with Spring
答案 2 :(得分:1)
@RunWith(SpringJUnit4ClassRunner.class)
确保测试在spring上下文中运行。如果你更换它,你就会失去它。
我想到的另一种方法是扩展SpringJunit4ClassRunner
,在那里提供您的自定义功能,并将其与@RunWith(..)
一起使用。因此,您将拥有spring上下文+您的附加功能。它将调用super.createTest(..)
,然后在测试中执行其他操作。
答案 3 :(得分:0)
受Simon解决方案的启发,您可以将TestContextManager与参数化运行器一起使用:
@RunWith(Parameterized.class)
@ContextConfiguration(locations = "classpath:/spring-context.xml")
public class MyTestClass {
@Parameters public static Collection data() {
// return parameters, following pattern in
// http://junit.org/apidocs/org/junit/runners/Parameterized.html
}
@Before
public void setUp() throws Exception {
new TestContextManager(getClass()).prepareTestInstance(this);
}
}
在这种情况下,我不确定是否处理@Transactional。
答案 4 :(得分:0)
我必须以编程方式处理交易(请参阅http://www.javathinking.com/2011/09/junit-parameterized-test-with-spring-autowiring-and-transactions/):
@RunWith(Parameterized.class)
@ContextConfiguration(locations = "classpath*:/testContext.xml")
public class MyTest {
@Autowired
PlatformTransactionManager transactionManager;
private TestContextManager testContextManager;
public MyTest (... parameters for test) {
// store parameters in instance variables
}
@Before
public void setUpSpringContext() throws Exception {
testContextManager = new TestContextManager(getClass());
testContextManager.prepareTestInstance(this);
}
@Parameterized.Parameters
public static Collection<Object[]> generateData() throws Exception {
ArrayList list = new ArrayList();
// add data for each test here
return list;
}
@Test
public void validDataShouldLoadFully() throws Exception {
new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
status.setRollbackOnly();
try {
... do cool stuff here
} catch (Exception e) {
throw new RuntimeException(e);
}
return null;
}
});
}
答案 5 :(得分:0)
您可以将SpringClassRule和SpringMethodRule用于此目的
@RunWith(Parameterized.class)
@ContextConfiguration(...)
public class FooTest {
@ClassRule
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
@Autowired
private Bar bar
@Parameters
public static Collection<Object[]> data() {
// return parameters, following pattern in
// http://junit.org/apidocs/org/junit/runners/Parameterized.html
}
@Test
public void someTest() {
bar.baz() //NullPointerException
}
}
答案 6 :(得分:0)
这是我在Spring Boot 1.5.7
中使其工作的方式:
将@RunWith(Parameterized.class)
批注添加到您的班级
将您的依赖项作为类字段注入:
@Autowired
private Bar bar;
将您的参数添加为类字段:
private final int qux;
private final Boolean corge;
private final String grault;
添加一个构造函数来初始化参数,如下所示:
public Foo(int qux, Boolean corge, String grault) throws Exception {
this.qux = qux;
this.corge = corge;
this.grault = grault;
new TestContextManager(getClass()).prepareTestInstance(this);
}
添加一个静态方法data
,该方法将返回一个Collection,该Collection包含每次迭代中您的参数值,并遵守将它们传递给构造函数的顺序:
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{ 1, Boolean.FALSE, "Hello" },
{ 2, Boolean.TRUE, null },
{ 3, null, "world" }
});
}
使用上面声明的类字段编写测试,如下所示:
@Test public void someTest(){
// Some arrangements
// Some actions
assertThat(myTestedIntValue, is(equalTo(qux));
assertThat(myTestedBooleanValue, is(equalTo(corge));
assertThat(myTestedStringValue, is(equalTo(grault));
}