iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java中怎么实现单元测试与集成测试
  • 715
分享到

Java中怎么实现单元测试与集成测试

2023-06-16 10:06:52 715人浏览 泡泡鱼
摘要

Java中怎么实现单元测试与集成测试,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Maven测试代码结构的组织我们知道在Maven工程结构中“src/test”目录是专门用

Java中怎么实现单元测试与集成测试,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

Maven测试代码结构的组织

我们知道在Maven工程结构中“src/test”目录是专门用于存放测试代码的,但令人痛苦的是Maven的标准目录结构只定义了这样一个测试目录,也就是说它本身是无法单独区分单元测试代码和集成测试代码的,这也是为什么很多人会把UT和IT代码同时写到"src/test"目录而导致“mvn  test”难以跑过的原因。

那么有什么办法可以友好地解决这个问题呢?在接下来的内容中我们以Maven构建spring  Boot项目为例来具体演示下在Maven中如何友好地分离UT及IT,具体步骤如下:

1)、首先我们创建一个基于Maven构建的Spring Boot项目,代码结构如下图所示:

Java中怎么实现单元测试与集成测试

如上图所示,在规划的目录结构中我们将IT的代码目录及资源文件目录单独分离在“src/integration-test”目录下,默认的“src/test”目录还是作为存放UT代码的目录,而Maven在构建的过程中默认只运行UT代码。这样即便IT代码由于网络、环境等原因无法正常执行,但也不至于影响到UT代码的运行。

2)、创建区分UT、IT代码的Maven Profiles文件

默认情况下Maven是无法主动识别“src/test”目录之外的测试代码的,所以当我们将IT代码抽象到"src/integration-test"目录之后,需要通过编写Maven  Profiles文件来进行区分,具体示意图如下:

Java中怎么实现单元测试与集成测试

如上图所示,我们可以在与“src”目录平行创建一个“profiles”的目录,其中分别用“dev”、“integration-test”目录中的config.properties文件来进行区分,其中dev目录下的config.properties文件的内容为:

profile=dev

而integration-test目录中的config.properties文件则为:

profile=integration-test

3)、通过pom.xml文件配置上述profiles文件生效规则

为了使得这些profiles文件生效,我们还需要在pom.xml文件中进行相应的配置。具体如下:

<!--定义关于区分集成测试及单元测试代码的profiles--> <profiles>     <!-- The Configuration of the development profile -->     <profile>         <id>dev</id>         <activation>             <activeByDefault>true</activeByDefault>         </activation>         <properties>             <build.profile.id>dev</build.profile.id>             <!--Only unit tests are run when the development profile is active-->             <skip.integration.tests>true</skip.integration.tests>             <skip.unit.tests>false</skip.unit.tests>         </properties>     </profile>     <!-- The Configuration of the integration-test profile -->     <profile>         <id>integration-test</id>         <properties>             <build.profile.id>integration-test</build.profile.id>             <!--Only integration tests are run when the integration-test profile is active-->             <skip.integration.tests>false</skip.integration.tests>             <skip.unit.tests>true</skip.unit.tests>         </properties>     </profile> </profiles>

上述内容先定义了区分dev及integration-test环境的的profile信息,接下来在build标签中定义资源信息及相关plugin,具体如下:

<build>     <finalName>${project.artifactId}</finalName>     <!--步骤1:单元测试代码、集成测试代码分离-->     <filters>         <filter>profiles/${build.profile.id}/config.properties</filter>     </filters>     <resources>         <resource>             <filtering>false</filtering>             <directory>src/main/java</directory>             <includes>                 <include>***.xml</include>                 <include>***.yml</include>             </includes>         </resource>         <!--步骤2:通过Profile区分Maven集成测试代码、单元测试代码目录-->         <resource>             <filtering>true</filtering>             <directory>src/main/resources</directory>             <includes>                 <include>***.xml</include>                 <include>***.yml</include>                 <include>***.properties</include>                                 </includes>                             </resource>                         </resources>                     </configuration>                 </execution>             </executions>         </plugin>         <!--步骤四:Runs unit tests -->         <plugin>             <groupId>org.apache.maven.plugins</groupId>             <artifactId>maven-surefire-plugin</artifactId>             <version>2.18</version>             <configuration>                 <!-- Skips unit tests if the value of skip.unit.tests property is true -->                 <skipTests>${skip.unit.tests}</skipTests>                 <!-- Excludes integration tests when unit tests are run -->                 <excludes>                     <exclude>**/IT*.java</exclude>                 </excludes>             </configuration>         </plugin>         <!--步骤五:Runs integration tests -->         <plugin>             <groupId>org.apache.maven.plugins</groupId>             <artifactId>maven-failsafe-plugin</artifactId>             <version>2.18</version>             <executions>                 <execution>                     <id>integration-tests</id>                     <Goals>                         <goal>integration-test</goal>                         <goal>verify</goal>                     </goals>                     <configuration>                         <skipTests>${skip.integration.tests}</skipTests>                     </configuration>                 </execution>             </executions>         </plugin>     </plugins> </build>

到这里我们就完成了基于Maven构建的Spring Boot项目的UT及IT代码目录的分离配置,此时对UT代码的执行还是通过默认“mvn  test”命令,而集成测试代码的运行则可以通过如下命令:

mvn clean verify -P integration-test

单元测试代码示例

通过前面的配置操作就完成了单元测试、集成测试代码目录的分离设置。在后续的开发过程中只需要将相应的测试代码写在对应的测试目录即可。接下来我们模拟一段业务逻辑并演示如何编写其对应的UT代码。具体如下:

Java中怎么实现单元测试与集成测试

如上图所示,参考mvc三层规范,我们编写了一个接口逻辑,该接口Controller层接收Http请求后调用Service层进行处理,而Service层处理逻辑时会调用Dao层操作数据库,并将具体信息插入数据库

那么我们编写单元测试(UT)代码时,针对的是单独的某个逻辑单元的测试,而不是从头到位的整个逻辑,它的运行不应该依赖于任何网络环境或其他组件,所有依赖的组件或网络都应该先进行Mock。以单元测试TestServceImpl中的“saveTest”方法为例,其UT代码编写如下:

@RunWith(SpringRunner.class) @SpringBootTest(classes = TestServiceImpl.class) @ActiveProfiles("test") public class TestServiceImplTest {      @Autowired     TestServiceImpl testServiceImpl;      @MockBean     TestDao testDao;      @Test     public void saveTest() {         //调用测试方法         testServiceImpl.saveTest("无敌码农微信公众号");         //验证执行测试的逻辑中是否调用过addUser方法         verify(testDao).addUser(any());     } }

如上所示UT代码,我们UT测试的主要对象为TestServiceImpl类,所以可以在@SpringBootTest注解中进行范围指定。而@ActiveProfiles("test")则表示代码中所依赖的系统参数,可以从测试资源目录resouces/application-test.yml文件中获得。

单元测试的主要目的是验证单元代码内的逻辑,对于所依赖的数据库Dao组件并不是测试的范围,但是没有该Dao组件对象,UT代码在执行的过程中也会报错,所以一般会通过@MockBean注解进行组件Mock,以此解决UT测试过程中的代码依赖问题。此时运行“mvn  test”命令:

Java中怎么实现单元测试与集成测试

单元测试代码得以正常执行!

集成测试代码示例

在Spring  Boot中UT代码的编写方式与IT代码类似,但是其执行范围是包括了整个上下文环境。我们以模拟从Controller层发起Http接口请求为例,来完整的测试整个接口的逻辑,并最终将数据存入数据库。具体测试代码如下:

@RunWith(SpringRunner.class) @SpringBootTest @ActiveProfiles("test") public class ITTestControllerTest {      @Autowired     TestController testController;      @Test     public void saveTest() {         testController.saveTest("无敌码农微信公众号");     } }

可以看到对于集成测试代码在@SpringBootTest中并没有指定具体的类,它的默认执行范围为整个应用的上下文环境。而代码中的依赖组件由于整个应用上下文都会被启动,所以依赖上并不会报错,可以理解为是一个正常启动的Spring  Boot应用。

需要注意的是由于IT代码的目录有独立的资源配置,所以相关的依赖配置,如数据库等需要在“src/integration-test/resouces/application-test.yml”文件中单独配置,例如:

spring:  application:     name: springboot-test-demo   #数据库逻辑   datasource:     url: jdbc:mysql://127.0.0.1:3306/test     username: root     passWord: 123456     type: com.alibaba.druid.pool.DruidDataSource     driver-class-name: com.Mysql.jdbc.Driver     separator: //  server:   port: 8080

此时运行集成测试命令“mvn clean verify -P integration-test”:

Java中怎么实现单元测试与集成测试

关于Java中怎么实现单元测试与集成测试问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网精选频道了解更多相关知识。

--结束END--

本文标题: Java中怎么实现单元测试与集成测试

本文链接: https://www.lsjlt.com/news/283149.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • c++中if elseif使用规则
    c++ 中 if-else if 语句的使用规则为:语法:if (条件1) { // 执行代码块 1} else if (条件 2) { // 执行代码块 2}// ...else ...
    99+
    2024-05-14
    c++
  • c++中的继承怎么写
    继承是一种允许类从现有类派生并访问其成员的强大机制。在 c++ 中,继承类型包括:单继承:一个子类从一个基类继承。多继承:一个子类从多个基类继承。层次继承:多个子类从同一个基类继承。多层...
    99+
    2024-05-14
    c++
  • c++中如何使用类和对象掌握目标
    在 c++ 中创建类和对象:使用 class 关键字定义类,包含数据成员和方法。使用对象名称和类名称创建对象。访问权限包括:公有、受保护和私有。数据成员是类的变量,每个对象拥有自己的副本...
    99+
    2024-05-14
    c++
  • c++中优先级是什么意思
    c++ 中的优先级规则:优先级高的操作符先执行,相同优先级的从左到右执行,括号可改变执行顺序。操作符优先级表包含从最高到最低的优先级列表,其中赋值运算符具有最低优先级。通过了解优先级,可...
    99+
    2024-05-14
    c++
  • c++中a+是什么意思
    c++ 中的 a+ 运算符表示自增运算符,用于将变量递增 1 并将结果存储在同一变量中。语法为 a++,用法包括循环和计数器。它可与后置递增运算符 ++a 交换使用,后者在表达式求值后递...
    99+
    2024-05-14
    c++
  • c++中a.b什么意思
    c++kquote>“a.b”表示对象“a”的成员“b”,用于访问对象成员,可用“对象名.成员名”的语法。它还可以用于访问嵌套成员,如“对象名.嵌套成员名.成员名”的语法。 c++...
    99+
    2024-05-14
    c++
  • C++ 并发编程库的优缺点
    c++++ 提供了多种并发编程库,满足不同场景下的需求。线程库 (std::thread) 易于使用但开销大;异步库 (std::async) 可异步执行任务,但 api 复杂;协程库 ...
    99+
    2024-05-14
    c++ 并发编程
  • 如何在 Golang 中备份数据库?
    在 golang 中备份数据库对于保护数据至关重要。可以使用标准库中的 database/sql 包,或第三方包如 github.com/go-sql-driver/mysql。具体步骤...
    99+
    2024-05-14
    golang 数据库备份 mysql git 标准库
  • 如何在 Golang 中优雅地处理错误?
    在 go 中,优雅处理错误包括:使用 error 类型;使用 errors 包函数和类型;自定义错误类型;遵循错误处理模式,包括关闭资源、检查错误、打印错误信息和处理或返回错误。 在 ...
    99+
    2024-05-14
    golang 错误处理
  • 如何构建 Golang RESTful API,并使用中间件进行身份验证?
    本文介绍了如何构建 golang restful api。首先,通过导入必要的库、定义数据模型和创建路由来构建 restful api。其次,使用 go-chi/chigot 和 go-...
    99+
    2024-05-14
    golang git
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作