springboot项目和普通的spring项目一样也可以做单元测试,一般是测试service层的方法,在进行项目构建的时候,需要在springboot默认依赖的基础上,再加上spring-boot-starter-test依赖,pom.xml文件如下所示:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
这里我们假定使用jpa操作数据库,然后我们需要定义实体类,编写dao层接口,service层接口。这里以User实体为例。
BaseEntity.java
package com.xxx.securitydemo.domain;
import java.util.Date;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
@MappedSuperclass
public class BaseEntity {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
protected Integer id;
protected Date modifyDate;
protected Date createDate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
User.java
package com.xxx.securitydemo.domain;
import javax.persistence.Entity;
@Entity
public class User extends BaseEntity{
private String username;
private String password;
private String mobile;
private int age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
配置类,本来这个示例是用来做springboot+security的,所以类名有些特殊意义,这里不妨碍使用,主要配置一个密码加密实体类,在单元测试类中会用到:
package com.xxx.securitydemo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
UserDao.java
package com.xxx.securitydemo.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.xxx.securitydemo.domain.User;
public interface UserDao extends JpaRepository<User,Integer>{
}
UserService.java
package com.xxx.securitydemo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xxx.securitydemo.dao.UserDao;
import com.xxx.securitydemo.domain.User;
@Service
public class UserService {
@Autowired
private UserDao userDao;
public User findById(Integer id) {
return userDao.findById(id).orElse(null);
}
public User save(User user) {
return userDao.save(user);
}
}
启动类 App.java
package com.xxx.securitydemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App {
public static void main( String[] args ){
SpringApplication.run(App.class, args);
}
}
application.yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql:///huali?useUnicode=true&useSSL=false&characterEncoding=UTF-8
username: root
password: root
jpa:
hibernate:
ddl-auto: update
单元测试类 UserServiceTest.java
package com.xxx.securitydemo;
import static org.junit.Assert.assertEquals;
import java.util.Date;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.context.junit4.SpringRunner;
import com.xxx.securitydemo.domain.User;
import com.xxx.securitydemo.service.UserService;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Autowired
private PasswordEncoder passwordEncoder;
@Test
public void insert() {
User user = new User();
user.setUsername("hadoop");
String password = passwordEncoder.encode("hadoop");
user.setPassword(password);
user.setAge(18);
user.setMobile("15011186301");
user.setCreateDate(new Date());
user.setModifyDate(new Date());
User result = userService.save(user);
assertEquals(result.getPassword(), password);
}
@Test
public void update() {
User user = userService.findById(1);
user.setCreateDate(new Date());
user.setModifyDate(new Date());
userService.save(user);
}
}
运行单元测试,鼠标点在单元测试类中的方法上,右键 Run As -> JUnit,控制台打印信息,没有报错的话,JUnit面板会显示绿条。
15:37:18.003 [main] DEBUG org.springframework.test.context.junit4.SpringJUnit4ClassRunner - SpringJUnit4ClassRunner constructor called with [class com.xxx.securitydemo.UserServiceTest]
15:37:18.008 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate]
15:37:18.015 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)]
15:37:18.031 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [com.xxx.securitydemo.UserServiceTest] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper]
15:37:18.041 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.xxx.securitydemo.UserServiceTest], using SpringBootContextLoader
15:37:18.043 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.xxx.securitydemo.UserServiceTest]: class path resource [com/xxx/securitydemo/UserServiceTest-context.xml] does not exist
15:37:18.044 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.xxx.securitydemo.UserServiceTest]: class path resource [com/xxx/securitydemo/UserServiceTestContext.groovy] does not exist
15:37:18.044 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [com.xxx.securitydemo.UserServiceTest]: no resource found for suffixes {-context.xml, Context.groovy}.
15:37:18.044 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [com.xxx.securitydemo.UserServiceTest]: UserServiceTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
15:37:18.075 [main] DEBUG org.springframework.test.context.support.ActiveProfilesUtils - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [com.xxx.securitydemo.UserServiceTest]
15:37:18.081 [main] DEBUG org.springframework.core.env.StandardEnvironment - Adding PropertySource 'systemProperties' with lowest search precedence
15:37:18.081 [main] DEBUG org.springframework.core.env.StandardEnvironment - Adding PropertySource 'systemEnvironment' with lowest search precedence
15:37:18.082 [main] DEBUG org.springframework.core.env.StandardEnvironment - Initialized StandardEnvironment with PropertySources [MapPropertySource@1773206895 {name='systemProperties', properties={java.runtime.name=Java(TM) SE Runtime Environment, sun.boot.library.path=D:\Program Files\Java\jdk1.8.0_212\jre\bin, java.vm.version=25.212-b10, java.vm.vendor=Oracle Corporation, java.vendor.url=http://java.oracle.com/, path.separator=;, java.vm.name=Java HotSpot(TM) 64-Bit Server VM, file.encoding.pkg=sun.io, user.country=CN, user.script=, sun.java.launcher=SUN_STANDARD, sun.os.patch.level=, java.vm.specification.name=Java Virtual Machine Specification, user.dir=D:\workspace\securitydemo, java.runtime.version=1.8.0_212-b10, java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment, java.endorsed.dirs=D:\Program Files\Java\jdk1.8.0_212\jre\lib\endorsed, os.arch=amd64, java.io.tmpdir=C:\Users\ADMINI~1\AppData\Local\Temp\, line.separator=
, java.vm.specification.vendor=Oracle Corporation, user.variant=, os.name=Windows 10, sun.jnu.encoding=GBK, java.library.path=D:\Program Files\Java\jdk1.8.0_212\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;D:/Program Files/Java/jdk1.8.0_212/bin/../jre/bin/server;D:/Program Files/Java/jdk1.8.0_212/bin/../jre/bin;D:/Program Files/Java/jdk1.8.0_212/bin/../jre/lib/amd64;C:\Program Files (x86)\NetSarang\Xshell 6\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;D:\Program Files\Java\jdk1.8.0_212\bin;D:\Program Files\Java\jdk1.8.0_212\jre\bin;C:\Program Files\TortoiseSVN\bin;C:\Program Files\Git\cmd;C:\Program Files\TortoiseGit\bin;D:\feiy\tools\apache-maven-3.3.9\bin;D:\feiy\tools\node-v10.16.3-win-x64;E:\app\mongodb-win32-x86_64\bin;E:\