使用 Spring Boot 在单元测试中配置集成测试或使用 Spring JDBC?
Posted
技术标签:
【中文标题】使用 Spring Boot 在单元测试中配置集成测试或使用 Spring JDBC?【英文标题】:Configure integration test or use Spring JDBC in Unit Test using Spring Boot? 【发布时间】:2015-06-14 07:30:41 【问题描述】:我正在使用最新版本的 Spring Boot、Spring JDBC 和 Spring Rest...
我的项目设置为一个典型的 Maven 项目,包含以下文件系统结构:
myproject
|
--src/main/java/com/myapp
--src/main/resource/application.properties
|
--src/test/java/com/myapp
--src/test/resources/application.properties
|
pom.xml
我的application.properties如下(连接本地mysql 5数据库):
spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=
spring.datasource.name=testdb
spring.datasource.initialize=true
spring.datasource.driverClassName=com.mysql.jdbc.Driver
MyDAO:
public interface MyDao
public List<App> findAllApps();
MyDaoImpl:
@Repository("myDao")
public class MyDaoImpl implements MyDao
@Autowired
JdbcTemplate jdbcTemplate;
public List<App> findAllApps()
List<App> apps = this.jdbcTemplate.query(
"select app_name from app",
new RowMapper<App>()
public App mapRow(ResultSet rs, int rowNum) throws SQLException
App app = new App();
app.setAppName(rs.getString("app_name"));
return app;
);
return apps;
它使用依赖注入在 MyService 类中调用:
@RestController
public class MyService
@Autowired
@Qualifier("myDao")
MyDao myDao;
@RequestMapping(value = "/apps", method = RequestMethod.GET, consumes = "text/plain", produces = "application/json")
public void process() throws JsonParseException, IOException
List<App> apps = myDao.findAllApps();
System.out.println(apps.toString());
这完全按照我的 RestController 中的说明工作......
但是,在典型的 JUnit 测试中:
public class MyServiceTest
@Autowired
@Qualifier("myDao")
MyDao myDao;
@Test
public void process()
List<App> apps = myDao.findAllApps();
对 myDao.findAllApps() 的调用返回 NullPointerException...
我什至尝试通过从命令行发出以下命令首先运行我的应用程序(使用嵌入式 tomcat):
mvn spring-boot:run
然而,一个非数据库特定的 JUnit 测试在 Eclipse 内或当我这样做时工作:
mvn clean install
问题:
如何设置它以便我可以运行集成测试,它实际上会从 MyServiceTest 访问我的数据库(或模拟数据库)?
为什么尝试注入 MyServiceTest for Spring JDBC 时依赖注入失败?
有没有办法设置我的单元测试来测试 Rest 调用?
非常感谢所有花时间阅读本文的人,非常感谢做出回应的人!
这是我的 pom.xml(根据 Eddu 的要求):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>myproject</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.2.RELEASE</version>
</parent>
<properties>
<java.version>1.7</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>org.jboss.repository.releases</id>
<name>JBoss Maven Release Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/releases</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
【问题讨论】:
可以附上pom.xml吗? Eddu,我编辑了我的原始帖子,并根据您的要求附加了完整 pom.xml 文件的内容。 你在你的应用程序中使用 spring-data-jpa 吗?或者您正在将 JdbcTemplate 用于自定义存储库? Eddu,JdbcTemplate 上面列出的 MyDaoImpl... 感谢您尝试帮助我。 【参考方案1】:您似乎没有在测试中加载 Spring 的上下文,因此没有执行依赖注入。你应该这样做:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=Application.class) //Application being your
// Spring boot base config class
public class MyServiceTest ...
@Autowired
@Qualifier("myDao")
MyDao myDao;
您可以在我的github 中查看示例
【讨论】:
鉴于它是 Spring Boot,那么@SpringApplicationConfiguration
可能比@ContextConfiguration
更好,因此它使用SpringApplicationContextLoader
。
WornOutSoles,感谢您的回复...为什么注入 jdbcTemplate 而不是我的 Dao?
史蒂夫,你能举个例子吗?有没有办法让服务器(或不同的服务器)在调用 JUnit 测试时运行?
考虑配置以在 spring 上下文中运行测试。此外,如果您不使用 spring-data-jpa,请通过 spring-boot-starter-jdbc 更改当前 spring-starter-data-jpa 依赖项,从而允许自动配置 JdbcTemplate。【参考方案2】:
谢谢大家!
史蒂夫 - 你是对的!
经过多次试验和磨难,@SpringApplicationConfiguration 起作用了:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes=Application.class)
Eddu Melendez - 我使用 spring-boot-starter-jdbc 删除了 spring-starter-data-jpa 依赖项,并从我的 pom.xml 文件中删除了 spring-jdbc 依赖项。
感谢大家帮助我解决这个问题!
【讨论】:
以上是关于使用 Spring Boot 在单元测试中配置集成测试或使用 Spring JDBC?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 集成 JUnit5,更优雅单元测试!