项目开发过程中,不少公司都要求写单元测试的代码,可以提高代码的质量,并且可以减少出现BUG的概率。

对于中小型公司来说,对单元测试不做硬性要求,不写最好。因为还是需要一定的工作量,在保证代码质量和性能

的前提下,再去考虑单元测试比较合适。有更好,没有也不影响项目的开发进度。自己所在的项目组对于单元测试

有要求,并且要求被测试代码的覆盖率达到20%及以上,每次发布版本的时候,变更覆盖率需要达标才能够发版。

每次写完代码后,基本都会被要求写单元测试的代码,或者是后期补单元测试的代码,总之都得写。

下面就聊聊自己在项目中是如何写单元测试的,使用的框架是Mockito框架,maven的依赖为,

        <dependency>

            <groupId>org.mockito</groupId>

            <artifactId>mockito-core</artifactId>

            <version>1.10.19</version>

            <scope>test</scope>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

        </dependency>

安装Squaretest插件.

 

 

 

 

 

选择需要进行单元测试的service实现类.

 

 

 

 

可以根据需要选择对应的JUnit版本

 

 

 

自己使用的配置为

 

 

 

生成的测试代码示例.

package applets.nature.service.impl;

 

import applets.nature.entiry.GiftExchangeEntiry;

import applets.nature.entiry.GiftInfo;

import applets.nature.mapper.GiftInfoMapper;

import applets.user.entiry.UserInfo;

import applets.user.service.UserService;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.mockito.InjectMocks;

import org.mockito.Mock;

import org.mockito.runners.MockitoJUnitRunner;

 

import java.util.Arrays;

import java.util.Collections;

import java.util.List;

 

import static org.assertj.core.api.Assertions.assertThat;

import static org.assertj.core.api.Assertions.assertThatThrownBy;

import static org.mockito.Mockito.when;

 

@RunWith(MockitoJUnitRunner.class)

public class GiftHandlerServiceImplTest {

 

    @Mock

    private GiftInfoMapper mockGiftInfoMapper;

    

    @Mock

    private UserService mockUserService;

 

    @InjectMocks

    private GiftHandlerServiceImpl giftHandlerServiceImplUnderTest;

 

    @Test

    public void testSelectGiftList() throws Exception {

        // Setup

        final GiftInfo giftInfo = new GiftInfo();

        giftInfo.setGiftId(“giftId”);

        giftInfo.setGiftType(“giftType”);

        giftInfo.setGiftTitle(“giftTitle”);

        giftInfo.setGiftDescription(“giftDescription”);

        giftInfo.setGiftFilePath(“giftFilePath”);

        giftInfo.setNeedLevel(0);

        giftInfo.setCreateTime(“createTime”);

        giftInfo.setCreateUser(“createUser”);

        giftInfo.setIsInvalid(0);

        giftInfo.setStatus(0);

        final List<GiftInfo> expectedResult = Arrays.asList(giftInfo);

 

        // Configure GiftInfoMapper.selectGiftList(…).

        final GiftInfo giftInfo1 = new GiftInfo();

        giftInfo1.setGiftId(“giftId”);

        giftInfo1.setGiftType(“giftType”);

        giftInfo1.setGiftTitle(“giftTitle”);

        giftInfo1.setGiftDescription(“giftDescription”);

        giftInfo1.setGiftFilePath(“giftFilePath”);

        giftInfo1.setNeedLevel(0);

        giftInfo1.setCreateTime(“createTime”);

        giftInfo1.setCreateUser(“createUser”);

        giftInfo1.setIsInvalid(0);

        giftInfo1.setStatus(0);

        final List<GiftInfo> giftInfos = Arrays.asList(giftInfo1);

        when(mockGiftInfoMapper.selectGiftList()).thenReturn(giftInfos);

 

        // Configure UserService.selectUserByOpenid(…).

        final UserInfo userInfo = new UserInfo();

        userInfo.setUserId(“userId”);

        userInfo.setUserName(“userName”);

        userInfo.setNickName(“nickName”);

        userInfo.setOpenid(“openid”);

        userInfo.setUserPhone(“userPhone”);

        userInfo.setAvatarUrl(“avatarUrl”);

        userInfo.setGender(0);

        userInfo.setCreateTime(“createTime”);

        userInfo.setRegistrationCode(“registrationCode”);

        userInfo.setUpdateTime(“updateTime”);

        when(mockUserService.selectUserByOpenid(“openid”)).thenReturn(userInfo);

 

        when(mockGiftInfoMapper.selectUserExchange(“openid”)).thenReturn(Arrays.asList(0));

 

        // Run the test

        final List<GiftInfo> result = giftHandlerServiceImplUnderTest.selectGiftList(“openid”);

 

        // Verify the results

        assertThat(result).isEqualTo(expectedResult);

    }

 

    @Test

    public void testSelectGiftList_GiftInfoMapperSelectGiftListReturnsNoItems() throws Exception {

        // Setup

        when(mockGiftInfoMapper.selectGiftList()).thenReturn(Collections.emptyList());

 

        // Configure UserService.selectUserByOpenid(…).

        final UserInfo userInfo = new UserInfo();

        userInfo.setUserId(“userId”);

        userInfo.setUserName(“userName”);

        userInfo.setNickName(“nickName”);

        userInfo.setOpenid(“openid”);

        userInfo.setUserPhone(“userPhone”);

        userInfo.setAvatarUrl(“avatarUrl”);

        userInfo.setGender(0);

        userInfo.setCreateTime(“createTime”);

        userInfo.setRegistrationCode(“registrationCode”);

        userInfo.setUpdateTime(“updateTime”);

        when(mockUserService.selectUserByOpenid(“openid”)).thenReturn(userInfo);

 

        when(mockGiftInfoMapper.selectUserExchange(“openid”)).thenReturn(Arrays.asList(0));

 

        // Run the test

        final List<GiftInfo> result = giftHandlerServiceImplUnderTest.selectGiftList(“openid”);

 

        // Verify the results

        assertThat(result).isEqualTo(Collections.emptyList());

    }

}

 

生成的代码说明,以查询方法SelectGiftLis为例:如果是测试service接口,一般使用serviceImpl来写测试用例,serviceImpl中一般会引入mapper接口。

测试代码中一般都是先生成一个对象,传入mapper接口方法的参数中,并且会创建一个mapper接口的返回对象。然后在使用serviceImpl来测试查

询方法,mock一个同样的查询参数,serviceImpl查询时就会有返回值。最后比对mapper接口返回的结果和serviceImpl查询返回的结果是否一致。

一致则通过测试,不一致则测试不通过。

 

点击如下图中的执行即可,效果如下.

 

 

 

有执行不成功的方法,自己在稍微修改一下测试的代码即可。

再次执行结果全部通过.

 

 

 

IDAE插件Squaretest是收费的,免费使用时间为30天。个人版本收费价格为35美元,有破解版本的小伙伴可以分享一下。

参考文章:https://zhuanlan.zhihu.com/p/318426230

 

完成第一步单元测试,下一步还需要收集测试之后的代码覆盖率。

添加依赖如下.

<dependency>

    <groupId>org.jacoco</groupId>

    <artifactId>jacoco-maven-plugin</artifactId>

    <version>0.8.3</version>

</dependency>

 

配置maven plugin 插件.

<plugin>

        <groupId>org.jacoco</groupId>

        <artifactId>jacoco-maven-plugin</artifactId>

        <version>0.8.3</version>

        <configuration>

          <includes>

            <include>com/**/*</include>

          </includes>

        </configuration>

        <executions>

          <execution>

            <id>pre-test</id>

            <goals>

              <goal>prepare-agent</goal>

            </goals>

          </execution>

          <execution>

            <id>post-test</id>

            <phase>test</phase>

            <goals>

              <goal>report</goal>

            </goals>

          </execution>

        </executions>

      </plugin>

参考博文.

https://www.cnblogs.com/fnlingnzb-learner/p/10637802.html

依次执行clean/compile/test

 

 

 

遇到问题,没有生成测试报告,也没报错信息。查看控制台信息,发现单元测试被跳过执行。

 

 

 

修改配置后,继续执行,发现如下信息,Skipping JaCoCo execution due to missing execution data file.

 

 

 

去必应搜索查找原因,

https://www.cnblogs.com/trimphNuan/p/13863269.html

说是配置文件中配置了argLine 配置项,导致出现问题,去除后重新执行,代码覆盖率生成成功。

 

 

 

 

 

可以点击进入查看每一行代码的覆盖率。绿色的表示测试时已经已经覆盖到该行的代码,粉色的表示未覆盖到。

 

 

 

至此,单元测试操作,并且生成代码覆盖率完成。

最后可以参考一下阿里巴巴写的一篇关于单元测试的博文:5个编写技巧,有效提高单元测试实践》

https://mp.weixin.qq.com/s/wQjFlXbK3MqKTUX2TfRR0g

原文地址:http://www.cnblogs.com/yilangcode/p/16900940.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性