Spring Boot 之JUnit
JUnit用于做单元测试,在实际开发中也是相对重要,因为有时候为了检查问题,测试SQL或测试某些Service功能,使用单元测试比启动项目,从页面上点还要快。
Spring Boot实现单元测试
Spring Boot test的POM配置
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency>
spring-boot-starter-test
支持常规的测试依赖,包括JUnit、Hamcrest、Mockito以及spring-test模块。
以DAO为例,至少需要两个配置文件
1. Application:用于启动启动Spring Boot
2. DataSourceConfig:用于链接数据库
Spring Boot启动类
package com.cherrypicks.hsbcpayme.config;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@Import(DataSourceConfig.class)
@ComponentScan(basePackages = "com.cherrypicks.hsbcpayme.dao")
public class Application {
}
DataSourceConfig
package com.cherrypicks.hsbcpayme.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
public class DataSourceConfig {
@Value("${spring.datasource.driverClassName}")
private String driverClassName;
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String userName;
@Value("${spring.datasource.pwd}")
private String pwd;
@Bean
public DataSource dataSource() {
return tomcatPoolingDataSource();
}
private DataSource tomcatPoolingDataSource() {
final org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(userName);
dataSource.setPassword(pwd);
dataSource.setInitialSize(5); // 连接池启动时创建的初始化连接数量(默认值为0)
dataSource.setMaxActive(20); // 连接池中可同时连接的最大的连接数
dataSource.setMaxIdle(12); // 连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限
dataSource.setMinIdle(0); // 连接池中最小的空闲的连接数,低于这个数量会被创建新的连接
dataSource.setMaxWait(60000); // 最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待
dataSource.setRemoveAbandonedTimeout(180); // 超过时间限制,回收没有用(废弃)的连接
dataSource.setRemoveAbandoned(true); // 超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收
dataSource.setTestOnBorrow(true);
dataSource.setTestOnReturn(true);
dataSource.setTestWhileIdle(true);
dataSource.setValidationQuery("SELECT 1");
dataSource.setTimeBetweenEvictionRunsMillis(1000 * 60 * 30); // 检查无效连接的时间间隔 设为30分钟
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
}
单元测试类
package com.cherrypicks.hsbcpayme.dao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert;
import com.cherrypicks.hsbcpayme.config.Application;
import com.cherrypicks.hsbcpayme.dao.SystemConfigDao;
import com.cherrypicks.hsbcpayme.model.SystemConfig;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class SystemConfigDaoTest {
@Autowired
private SystemConfigDao systemConfigDao;
@Test
public void testGetByKey() {
final SystemConfig systemConfig = systemConfigDao.getByKey("key");
Assert.notNull(systemConfig);
Assert.isTrue("value".equals(systemConfig.getConfigValue()));
}
@Test
public void testFindAll() {
Assert.notEmpty(systemConfigDao.findAll());
}
}
@RunWith(SpringJUnit4ClassRunner.class)
SpringJUnit支持,由此引入Spring-Test框架支持!
@SpringApplicationConfiguration(classes = SpringBootSampleApplication.class)
指定我们SpringBoot工程的Application启动类
@Test
要运行单元测试的方法
简单Spring的单元测试
以前Spring依赖
<!-- unit test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
不需要Spring启动类,但是要在XML配置DataSource
<context:annotation-config />
<context:component-scan base-package="com.cherrypicks.appsdollar.dao" />
<!-- db2 source -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" lazy-init="false">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="idleConnectionTestPeriod" value="60" />
<property name="testConnectionOnCheckout" value="false" />
<property name="initialPoolSize" value="2" />
<property name="minPoolSize" value="10" />
<property name="maxPoolSize" value="80" />
<property name="acquireIncrement" value="1" />
<property name="acquireRetryAttempts" value="1" />
<property name="maxIdleTime" value="6000" />
<property name="maxStatements" value="0" />
</bean>
单元测试类
package com.cherrypicks.appsdollar.dao;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.cherrypicks.appsdollar.base.model.enums.Lang;
import com.cherrypicks.appsdollar.base.test.JUnit4SpringTest;
public class CategoryDaoTest extends JUnit4SpringTest {
@Autowired
private CategoryDao categoryDao;
@Autowired
private CategoryLangDao categoryLangDao;
@Test
public void findAppContent() {
categoryLangDao.findByTitlePartyIdOsLang("asdfasdf", Lang.EN_US.toStringValue(), 1L, 1);
}
}
两者相比较
1. Spring的依赖写少了
2. 不需要XML配置,用Java配置代替
3. 单元测试类,Spring用注解代替了继承
参考:
http://blog.csdn.net/catoop/article/details/50752964
http://blog.sina.com.cn/s/blog_798f713f0102wiy5.html