如何更好的做单元测试(下)

作者 : 开心源码 本文共3861个字,预计阅读时间需要10分钟 发布时间: 2022-05-12 共190人阅读

SpringBoot环境下的测试方法

以下例子可以在spring-boot-test中找到。

???????Spring框架实际上是依靠SpringBoot完成了续命,由它焕发了第二春,打开了一个全新的战场。在今天微服务大放异彩的环境下,针对SpringBoot的测试也会有所不同。

???????SpringBoot实际是用来启动你的应用,所以它会有配置以及一系列商定大于配置的环境准备,所以需要依赖spring-boot-test支持来完成单元测试。

修改单元测试

???????假如需要在单元测试启动时启动SpringBoot,需要做一下相关的配置,添加少量注解。

依赖

???????添加依赖:

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-test</artifactId>    <scope>test</scope></dependency>

注解

???????和JavaConfig的方式非常相似,通过注解可以公告该测试是SpringBootTest,并且可以指定运行的SpringBoot容器的配置。

@SpringBootTest(classes = SpringBootMemberTest.Config.class)@TestPropertySource(locations = "classpath:test-application.properties")@RunWith(SpringRunner.class)public class SpringBootMemberTest {
注解说明
SpringBootTest形容了该SpringBoot单元测试是根据哪个配合来启动容器
TestPropertySource应用的配置使用哪个

配置

???????通过注解可以公告按照何种方式去执行测试,以及测试的Spring容器如何组装,还或者缺在Spring容器中如何配置Bean。

@SpringBootTest(classes = SpringBootMemberTest.Config.class)@TestPropertySource(locations = "classpath:test-application.properties")@RunWith(SpringRunner.class)public class SpringBootMemberTest {    @Autowired    private Environment env;    @MockBean    private UserDAO userDAO;    @Autowired    private MemberService memberService;    @Test    public void environment() {        Assert.assertEquals("Alibaba", env.getProperty("brand-owner.name"));    }    @Before    public void init() {        Mockito.when(userDAO.insertMember(Mockito.any())).thenReturn(System.currentTimeMillis());    }    @Test    public void insert_member() {        System.out.println(memberService.insertMember("windowsxp", "abc123"));        Assert.assertNotNull(memberService.insertMember("windowsxp", "abc123"));    }    @Configuration    static class Config {        @Bean        public MemberService memberService(UserDAO userDAO) {            MemberServiceImpl memberService =  new MemberServiceImpl();            memberService.setUserDAO(userDAO);            return memberService;        }    }}

???????可以看到新添加了一个注解MockBean,这个用来帮助我们创立一个Mock的UserDAO,而不用通过编码来进行创立,回忆之前在classic以及javaconfig中的Mock方式,都需要调用Mockito.mock(Class type)方法来创立一个Mock对象,而在SpringBootTest中就不需要了,直接在成员变量上添加MockBean的注解即可以了。

???????同时可以看到在单元测试中添加了一个注入属性,Environment,它代表Spring运行的环境,可以从中获取配置,以下是test-application.application中的内容:

brand-owner.name=Alibababrand-owner.company=Alibaba-inc.

???????在environment测试方法中,可以访问测试的配置内容,从这里可以看到SpringBootTestspring-test基础上,除了启动一个Spring容器,还准备好了一个SpringBoot运行时环境。

???????但是从侧面上讲,使用SpringBootTest就依赖了运行时环境,这不是一个好的选择,所以在大多数情况下,对于代码的单元测试spring-test即可以完全应对。

单元测试覆盖率

???????就像刻意的刷分数一样,单元测试覆盖率也是一个我们追求的目标,当单元测试行覆盖率超过70%的时候,整个项目的质量会很不错。持续稳固的单元测试覆盖率,会保障一个应用一直处于较稳固的状态,后续投入维护的资源会降低。

???????在不少IDE中,如:IDEA,都内置了统计单元测试的工具,只要要按照package运行测试就可,在这里我们不依赖具体的IDE,而是用maven插件来做。

jacoco

???????该插件对java8的语法支持较好,在pom文件中添加配置。

<plugin>    <groupId>org.jacoco</groupId>    <artifactId>jacoco-maven-plugin</artifactId>    <version>0.8.1</version>    <executions>        <execution>            <id>prepare-agent</id>            <goals>                <goal>prepare-agent</goal>            </goals>        </execution>        <execution>            <id>report</id>            <phase>prepare-package</phase>            <goals>                <goal>report</goal>            </goals>        </execution>        <execution>            <id>post-unit-test</id>            <phase>test</phase>            <goals>                <goal>report</goal>            </goals>            <configuration>                <dataFile>target/jacoco.exec</dataFile>                <outputDirectory>target/jacoco-ut</outputDirectory>            </configuration>        </execution>    </executions></plugin>

???????当运行mvn test时会生产单元测试覆盖率报告。

位置一般在项目的 target/jacoco-ut 目录下。

覆盖率

???????打开目录下的index.html可以看到各个类的覆盖率情况。

<center>
<img src=”https://alpic.fanquanwang.com/kx3x/uppic/chapter6-118612.png” />
</center>

缺失路径

???????点击到对应的package中的类,可以查看缺失的测试路径,这样即可以指导哪些分支没有归入单测。

<center>
<img src=”https://alpic.fanquanwang.com/kx3x/uppic/chapter6-218614.png” />
</center>

测试驱动开发简介

???????测试驱动开发的基本思想就是在开发功能代码之前,先编写测试代码,而后只编写使测试通过的功能代码,从而以测试来驱动整个开发过程的进行。这有助于编写简洁可用和高质量的代码,有很高的灵活性和健壮性,能快速响应变化,并加速开发过程。

测试开发驱动模式

???????测试驱动开发的基本过程如下:

  • 快速新添加一个测试
  • 运行所有的测试(有时候只要要运行一个或者一部分),发现新添加的测试不能通过
  • 做少量小小的改动,尽快地让测试程序可运行,为此可以在程序中使用少量不合情理的方法
  • 运行所有的测试,并且一律通过
  • 重构代码,以消除重复设计,优化设计结构

???????简单来说,就是不可运行/可运行/重构——这正是测试驱动开发的口号。

可取之处

???????测试驱动开发能够让代码上生产环境之前,能够以使用者的角度审视编写的代码:

  • 假如代码难测,那就是对问题的分析还没有到位
  • 假如大量的Mock,那就是依赖过于复杂

???????除了能够通过反向刺激让我们看到代码的不足,它还能以使用者的角度去看:

  • 这个方法命名能否够妥帖
  • 别人用这个函数会误用吗
  • 这个类是不是承担了过多的职责

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 如何更好的做单元测试(下)

发表回复