JDBC支持
JdbcTestUtils
countRowsInTable(..): counts the number of rows in the given table countRowsInTableWhere(..): counts the number of rows in the given table, using the provided WHERE clause deleteFromTables(..): deletes all rows from the specified tables deleteFromTableWhere(..): deletes rows from the given table, using the provided WHERE clause dropTables(..): drops the specified tables
创建内嵌数据库
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource () {
return new EmbeddedDatabaseBuilder()
.generateUniqueName(true )
.setType(H2)
.setScriptEncoding("UTF-8" )
.ignoreFailedDrops(true )
.addScript("schema.sql" )
.addScripts("user_data.sql" , "country_data.sql" )
.build();
}
}
测试
public class DataAccessIntegrationTestTemplate {
private EmbeddedDatabase db;
@Before
public void setUp () {
db = new EmbeddedDatabaseBuilder()
.generateUniqueName(true )
.addDefaultScripts()
.build();
}
@Test
public void testDataAccess () {
JdbcTemplate template = new JdbcTemplate(db);
template.query( );
}
@After
public void tearDown () {
db.shutdown();
}
}
注解
@BootstrapWith:一个用于配置Spring TestContext框架如何引导的类级别的注解。具体地说,@BootstrapWith用于指定一个自定义的TestContextBootstrapper @ContextConfiguration:定义了类级别的元数据来决定如何为集成测试来加载和配置应用程序上下文。具体地说,@ContextConfiguration声明了用于加载上下文的应用程序上下文资源路径和注解类。
@ContextConfiguration(classes = TestConfig.class)
public class ConfigClassApplicationContextTests {
}
@ContextConfiguration("/test-config.xml" )
public class XmlApplicationContextTests {
}
@ContextConfiguration(initializers = CustomContextIntializer.class)
public class ContextInitializerTests {
}
@ContextConfiguration(locations = "/test-context.xml" , loader = CustomContextLoader.class)
public class CustomLoaderXmlApplicationContextTests {
}
@WebAppConfiguration:是一个用于声明集成测试所加载的ApplicationContext须是WebApplicationContext的类级别的注解。测试类的@WebAppConfiguration注解只是为了保证用于测试的WebApplicationContext会被加载,它使用”file:src/main/webapp”路径默认值作为web应用的根路径(即,资源基路径)。资源基路径用于幕后创建一个MockServletContext作为测试的WebApplicationContext的ServletContext。
@ContextConfiguration
@WebAppConfiguration
public class WebAppTests {
}
@ContextHierarchy:是一个用于为集成测试定义ApplicationContext层次结构的类级别的注解。@ContextHierarchy应该声明一个或多个@ContextConfiguration实例列表,其中每一个定义上下文层次结构的一个层次。下面的例子展示了在同一个测试类中@ContextHierarchy的使用方法。但是,@ContextHierarchy一样可以用于测试类的层次结构中。
@WebAppConfiguration
@ContextHierarchy ({
@ContextConfiguration (classes = AppConfig.class),
@ContextConfiguration (classes = WebConfig.class)
})
public class WebIntegrationTests {
}
@ActiveProfiles:是一个用于当集成测试加载ApplicationContext的时候声明哪一个bean definition profiles被激活的类级别的注解。
@ContextConfiguration
@ActiveProfiles ({"dev" , "integration" })
public class DeveloperIntegrationTests {
}
@TestPropertySource:是一个用于为集成测试加载ApplicationContext时配置属性文件的位置和增加到Environment中的PropertySources集中的内联属性的类级别的注解。测试属性源比那些从系统环境或者Java系统属性以及通过@PropertySource或者编程方式声明方式增加的属性源具有更高的优先级。而且,内联属性比从资源路径加载的属性具有更高的优先级。
@ContextConfiguration
@TestPropertySource ("/test.properties" )
public class MyIntegrationTests {
}
@ContextConfiguration
@TestPropertySource (properties = { "timezone = GMT" , "port: 4242" })
public class MyIntegrationTests {
}
@DirtiesContext:指明测试执行期间该Spring应用程序上下文已经被弄脏(也就是说通过某种方式被更改或者破坏——比如,更改单例bean的状态)。当应用程序上下文被标为”脏”,它将从测试框架缓存中被移除并关闭。因此,Spring容器将为随后需要同样配置元数据的测试而被重建。@DirtiesContext可以在同一个类或者类层次结构中的类级别和方法级别中使用。在这个场景下,应用程序上下文将在任意此注解的方法之前或之后以及当前测试类之前或之后被标为“脏”,这取决于配置的methodMode和classMode。 @TestExecutionListeners:定义了一个类级别的元数据,用于配置需要用TestContextManager进行注册的TestExecutionListener实现。通常,@TestExecutionListeners与@ContextConfiguration一起使用。
@ContextConfiguration
@TestExecutionListeners ({CustomTestExecutionListener.class, AnotherTestExecutionListener.class})
public class CustomTestExecutionListenerTests {
}
@Commit:指定事务性的测试方法在测试方法执行完成后对事务进行提交。@Commit可以用作@Rollback(false)的直接替代,以更好的传达代码的意图。和@Rollback一样,@Commit可以在类层次或者方法层级声明。
@Commit
@Test
public void testProcessWithoutRollback() {
// ...
}
@Rollback:指明当测试方法执行完毕的时候是否对事务性方法中的事务进行回滚。如果为true,则进行回滚;否则,则提交(请参加@Commit)。在Spring TestContext框架中,集成测试默认的Rollback语义为true,即使你不显示的指定它。当被声明为方法级别的注解,则@Rollback为特定的方法指定回滚语义,并覆盖类级别的@Rollback和@Commit语义。
@Rollback(false)
@Test
public void testProcessWithoutRollback() {
// ...
}
@BeforeTransaction指明通过Spring的@Transactional注解配置为需要在事务中执行的测试方法在事务开始之前先执行注解的void方法。从Spring框架4.3版本起,@BeforeTransaction方法不再需要为public并可能被声明为基于Java8的接口的默认方法。
@BeforeTransaction
void beforeTransaction() {
}
@AfterTransaction指明通过Spring的@Transactional注解配置为需要在事务中执行的测试方法在事务结束之后执行注解的void方法。从Spring框架4.3版本起,@AfterTransaction方法不再需要为public并可能被声明为基于Java8的接口的默认方法。 @Sql:用于注解测试类或者测试方法,以让在集成测试过程中配置的SQL脚本能够在给定的的数据库中得到执行。
@Test
@Sql ({"/test-schema.sql" , "/test-user-data.sql" })
public void userTest {
}
@SqlConfig:定义了用于决定如何解析和执行通过@Sql注解配置的SQL脚本。
@Test
@Sql (
scripts = "/test-user-data.sql" ,
config = @SqlConfig (commentPrefix = "`" , separator = "@@" )
)
public void userTest {
}
@SqlGroup:是一个用于聚合几个@Sql注解的容器注解。@SqlGroup可以直接使用,通过声明几个嵌套的@Sql注解,也可以与Java8的可重复注解支持协同使用,即简单地在同一个类或方法上声明几个@Sql注解,隐式地产生这个容器注解。
@Test
@SqlGroup ({
@Sql (scripts = "/test-schema.sql" , config = @SqlConfig (commentPrefix = "`" )),
@Sql ("/test-user-data.sql" )
)}
public void userTest {
}
@Timed用于指明被注解的测试必须在指定的时限(毫秒)内结束。如果测试超过指定时限,就当作测试失败。时限包括测试方法本身所耗费的时间,包括任何重复(请查看@Repeat)及任意初始化和销毁所用的时间。Spring的@Timed注解与JUnit 4的@Test(timeout=…)支持相比具有不同的语义。确切地说,由于在JUnit 4中处理方法执行超时的方式(也就是,在独立线程中执行该测试方法),如果一个测试方法执行时间太长,@Test(timeout=…)将直接判定该测试失败。而Spring的@Timed则不直接判定失败而是等待测试完成。
@Timed (millis=1000 )
public void testProcessWithOneSecondTimeout () {
}
@Repeat指明该测试方法需被重复执行。注解指定该测试方法被重复的次数。重复的范围包括该测试方法自身也包括相应的初始化和销毁方法。
@Repeat(10 )
@Test
public void testProcessRepeatedly() {
// ...
}
JUnit Jupiter扩展
@SpringJUnitConfig:是将@ExtendWith(SpringExtension.class) from JUnit Jupiter 和@ContextConfiguration组合起来的一个注解
@SpringJUnitConfig (TestConfig.class)
class ConfigurationClassJUnitJupiterSpringTests {
// class body ...
}
@SpringJUnitConfig (locations = "/test-config.xml" )
class XmlJUnitJupiterSpringTests {
// class body ...
}
@SpringJUnitWebConfig:是将@ExtendWith(SpringExtension.class) from JUnit Jupiter 和@ContextConfiguration和@WebAppConfiguration 组合起来的一个注解
@SpringJUnitWebConfig (TestConfig.class)
class ConfigurationClassJUnitJupiterSpringWebTests {
// class body ...
}
@SpringJUnitWebConfig (locations = "/test-config.xml" )
class XmlJUnitJupiterSpringWebTests {
// class body ...
}
@EnabledIf和@DisabledIf:使用spel表达式
@Target ({ ElementType .TYPE , ElementType .METHOD })
@Retention (RetentionPolicy .RUNTIME )
@EnabledIf (
expression = "#{systemProperties['os.name' ].toLowerCase().contains('mac' )} " ,
reason = "Enabled on Mac OS"
)
public @interface EnabledOnMac {}
@Target ({ ElementType .TYPE , ElementType .METHOD })
@Retention (RetentionPolicy .RUNTIME )
@DisabledIf (
expression = "#{systemProperties['os.name' ].toLowerCase().contains('mac' )} " ,
reason = "Disabled on Mac OS"
)
public @interface DisabledOnMac {}
Spring TestContext Framework
@RunWith (SpringRunner .class )
Spring MVC Test Framework
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringJUnitWebConfig (locations = "test-servlet-context.xml" )
class ExampleTests {
private MockMvc mockMvc;
@BeforeEach
void setup(WebApplicationContext wac) {
this .mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
void getAccount() throws Exception {
this .mockMvc.perform(get("/accounts/1" )
.accept(MediaType.parseMediaType("application/json;charset=UTF-8" )))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json" ))
.andExpect(jsonPath("$.name" ).value("Lee" ));
}
}
MockMVc mockMvc = standaloneSetup(new MusicController())
.defaultRequest(get("/" ).accept(MediaType.APPLICATION_JSON))
.alwaysExpect(status().isOk())
.alwaysExpect(content().contentType("application/json;charset=UTF-8" ))
.build();
mockMvc.perform(post("/hotels/{id}" , 42 ).accept(MediaType.APPLICATION_JSON));
mockMvc.perform(multipart("/doc" ).file("a1" , "ABC" .getBytes("UTF-8" )));
mockMvc.perform(get("/hotels" ).param("foo" , "bar" ));
mockMvc = standaloneSetup(new PersonController()).addFilters(new CharacterEncodingFilter()).build();