添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • 保护已经实现的功能不被破坏。
  • 只针对某一个功能点写测试,比如独立测试某类中的某个方法。但这个类和方法本身不是独立的,可能会去调用其他的类或方法。我们可以采用Mockito和PowerMock两种工具,来虚拟那些外部的、不容易构造的对象:

  • Mockito:适用于大多数标准的单元测试。

  • PowerMock

  • PowerMock在Mockito的基础上,额外增加了更多case(如static Method,final method, 枚举类, private method和Constructor)
  • PowerMock写法与Mockito基本相同,这是因为PowerMock是从Mockito的一个特殊的API衍化而来。比如当添加PowerMock Junit-module的maven依赖时时,其实还要导入Mockito-API。
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <scope>test</scope>
    </dependency>

    <dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <scope>test</scope>
    </dependency>

    Mockito

    通过创建mock或spy对象,并制定具体返回规则来实现模拟的功能:

  • mock对象对于未指定处理规则的调用,会按方法返回值类型返回该类型的默认值(如int、long则返回0,boolean则返回false,对象则返回null,void则什么都不做)
  • spy对象在未指定处理规则时则会直接调用真实方法。
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public class OpenServiceImplTest {
    // @InjectMocks真正需要被测试的类
    @InjectMocks
    private final IOpenService openService = new OpenServiceImpl();

    // @Mock创建虚拟对象(外部类等)
    @Mock
    private IOpenWorkOrderDao openWorkOrderDao;

    @Mock
    private ITunnelService tunnelService;

    @Before
    public void setUp() {
    MockitoAnnotations.initMocks(this);
    }
    @Test
    public void getOpenDetailTest() {
    final int id = 321;
    final OpenWorkOrderEntity openWorkOrderEntity = new OpenWorkOrderEntity() {{
    this.setId(id);
    this.setWorkOrderNo("12");
    this.setCustomName("tom");
    this.setApnType(1);
    }};

    // mock的发生时机是当程序执行至”when-method-call-then-return”之类的语句时,可以测试类的逻辑流程
    Mockito.when(openWorkOrderDao.selectOpenWorkOrderById(anyInt())).thenReturn(openWorkOrderEntity);
    Mockito.doNothing().when(tunnelService).getTunnelInfo(any(OpenDetailDto.class), anyInt(), anyInt());

    final OpenDetailDto openDetailDtoResult = openService.getOpenDetail(id);
    // Assertions.assertThat(openDetailDtoResult.getId()).isEqualTo(321);
    Assertions.assertThat(openDetailDtoResult)
    .extracting("id", "workOrderNo", "customName", "apnType")
    .contains(
    321, "12", "name", 1
    );
    }

    PowerMock

    1
    @RunWith(PowerMockRunner.class)

    Spring Boot

    SpringBoot 也是基于 Junit 进行单位测试的。

    spring-boot-starter-test这个依赖中包含了:

  • JUnit:Java 应用程序单元测试标准类库。
  • Spring Test & Spring Boot Test:Spring Boot 应用程序功能集成化测试支持。
  • Mockito:一个Java Mock测试框架。
  • AssertJ:一个轻量级的断言类库。
  • Hamcrest:一个对象匹配器类库。
  • JSONassert:一个用于JSON的断言库。
  • JsonPath:一个JSON操作类库。
  • 1
    2
    3
    4
    5
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>

    打开IDEA,在任意类名、任意接口名上,按 ctrl+shift+t ,选择 Create New Test 。然后根据提示操作(默认即可),点击确认,就在项目的/test/java下的对应包里,生成了与类对应的测试类。

    或者,在任意类名、任意接口名上,按 Alt+Insert ,然后选择 Test 。然后根据提示操作(默认即可),点击确认,就在项目的/test/java下的对应包里,生成了与类对应的测试类。

    如果没有“Create New Test”,请更新idea版本或者在plugin中安装插件JUnitGenerator V2.0(仅支持到JUNIT4、3等老版本。idea升级后新版本不需要安装此插件)。

    参阅: Spring Boot:快速创建单元测试_e6486883的博客-CSDN博客_springboot创建测试单元

    代码覆盖率测试工具

    Intellij IDEA集成了三种分析单元测试覆盖率的工具,包括IntelliJ IDEA、JaCoCo和Emma。

  • IntelliJ IDEA,是idea默认自带的插件,统计出来的覆盖率只包含classes、method、line,不详细
  • JaCoCo,最常用。需要首先在Idea中选择JaCoCo模式,而后在项目的maven polm文件中进行依赖配置。
  • IntelliJ IDEA使用步骤
    1. Run → Edit Configurations

    2. 选择测试范围:指定要测试的包路径或类文件等

    3. 右键选择 Run 'All Tests' with Coverage ,开始运行所有测试用例。运行完后,IDE将会在 Coverage 工具窗显示所有include进来的包/类的覆盖率数据,也可以导出测试覆盖率报告 。
    4. 红色方块:没有覆盖(在这一行中没有分支被执行)
    5. 黄色方块:部分覆盖(这一行的分支中只有一部分被执行)
    6. 绿色方块:完全覆盖(这一行的所有分支都被执行)
    7. JaCoCo使用步骤
      1. Run → Edit Configurations中设置为JaCoCo
      2. maven配置
      3. 添加依赖:配置JaCoCo插件一定注意和JDK版本的对应关系,如果是jdk1.8,则插件一定要用最新版,不然会报错误。g’g

        1
        2
        3
        4
        5
        <dependency>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.5</version>
        </dependency>

        配置plugins

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        70
        <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.5</version>
        <configuration>
        <destFile>target/coverage-reports/jacoco-unit.exec</destFile>
        <dataFile>target/coverage-reports/jacoco-unit.exec</dataFile>
        <includes>
        <include>**/service/**</include>
        <include>**/controller/**</include>
        <!--<include>**/service/impl/*.class</include>-->
        </includes>

        <!-- rules里面指定覆盖规则,在覆盖率不满足的情况下,mvn install会报错Build Failure -->
        <rules>
        <rule implementation="org.jacoco.maven.RuleConfiguration">
        <element>BUNDLE</element>
        <limits>
        <!-- 指定方法覆盖到50% -->
        <limit implementation="org.jacoco.report.check.Limit">
        <counter>METHOD</counter>
        <value>COVEREDRATIO</value>
        <minimum>0.50</minimum>
        </limit>

        <!-- 指定分支覆盖到50% -->
        <limit implementation="org.jacoco.report.check.Limit">
        <counter>BRANCH</counter>
        <value>COVEREDRATIO</value>
        <minimum>0.50</minimum>
        </limit>

        <!-- 指定类覆盖到100%,不能遗失任何类 -->
        <limit implementation="org.jacoco.report.check.Limit">
        <counter>CLASS</counter>
        <value>MISSEDCOUNT</value>
        <maximum>0</maximum>
        </limit>
        </limits>
        </rule>
        </rules>
        </configuration>
        <executions>
        <execution>
        <!--在maven的initialize阶段,将Jacoco的runtime agent作为VM的一个参数传给被测程序,用于监控JVM中的调用。-->
        <id>jacoco-initialize</id>
        <goals>
        <goal>prepare-agent</goal>
        </goals>
        </execution>

        <!--这个check:对代码进行检测,控制项目构建成功还是失败-->
        <execution>
        <id>check</id>
        <goals>
        <goal>check</goal>
        </goals>
        </execution>

        <!--report:对代码进行检测,然后生成index.html在 target/site/index.html中可以查看检测的详细结果-->
        <execution>
        <id>jacoco-site</id>
        <phase>package</phase>
        <!--<phase>test</phase>写上test的时候会自动出现site文件夹,而不需执行下面的jacoco:report步骤,推荐-->
        <goals>
        <goal>report</goal>
        </goals>
        </execution>
        </executions>
        </plugin>

        刷新maven,会发现多了一个插件:

        arget文件夹中会多出一个site文件夹(如果没有点击上述jacoco:report)。点击里面的index.html文件,用浏览器打开即可看到测试报告。

      4. maven配置
      5. 执行 mvn install 或者 mvn test 命令,获得 JaCoCo的统计数据。执行完以后,target/site/jacoco/目录下会生成一个index.html文件,这是统计数据总览页面,可以在浏览器打开查看。

        集成多模块报告

        执行 mvn clean package (clean install)命令后,在项目的 ROOT\target\site\目录会生成 jacoco目录

        断言

        Assert