您的位置:首页技术文章
文章详情页

SpringBoot2 集成测试组件的七种方法

【字号: 日期:2023-03-08 09:53:02浏览:2作者:猪猪
目录一、背景描述二、PostMan工具三、Swagger文档四、TestRestTemplate类五、Http请求模式六、Service层测试七、MockMvc方式八、Mockito测试九、源代码地址一、背景描述

在版本开发中,时间段大致的划分为:需求,开发,测试;

需求阶段:理解需求做好接口设计;开发阶段:完成功能开发和对接;测试上线:自测,提测,修复,上线;实际上开发阶段两个核心的工作,开发和流程自测,自测的根本目的是为自己提前解决可能出现的问题;如果缺少自测和提测两个关键步骤,那么问题就会被传递给更多的用户,产生更多的资源消耗;

自测是于开发而言,提测是对专业的测试人员而言,如果尽可能在自测阶段就发现问题,并解决问题,那么一个问题就不会影响到团队协作上的更多人员,如果一个简单的问题上升到团队协作层面,很可能会导致问题本身被放大。

工欲善其事必先利其器,开发如果要做好自测流程,学会使用工具提高效率是十分关键的,自测的关键在于发现问题和解决问题,所以选择好用和高效的工具可以极大的降低自测的时间消耗。

二、PostMan工具

PostMan很常用的接口测试工具,开发过程中快速测试接口,功能强大并且简单方便,不但可以单个接口测试,也可以对接口分块管理批量运行:

SpringBoot2 集成测试组件的七种方法

整体来说工具比较好用,适应于开发阶段的接口快速测试,或者在解决问题的过程中单个接口的测试,同时对测试参数有存储和记忆能力,这也是受欢迎的一大原因。

但是该工具不适应于复杂的流程化测试,例如需要根据上次接口的响应报文做分别处理,或者下次请求需要填充某个接口响应的数据。

三、Swagger文档

Swagger管理接口文档,是当下服务中很常用的组件,通过对接口和对象的简单注释,快速生成接口描述信息,并且可以对接口发送请求,协助调试,该文档在前后端联调中极大的提高效率。

接口文档的管理本身是一件麻烦事,接口通常会根据业务不断的调整,如果单独维护一份接口文档,需要付出很多时间成本,并且容易出问题,利用swagger就可以避免这个问题。

借助swagger注解标记对象

@TableName('jt_activity')@ApiModel(value='活动PO对象', description='活动信息表【jt_activity】')public class Activity { @ApiModelProperty(value = '主键ID') @TableId(type = IdType.AUTO) private Integer id; @ApiModelProperty(value = '活动主题') private String activityTitle; @ApiModelProperty(value = '联系号码') private String contactPhone; @ApiModelProperty(value = '1线上、2线下') private Integer isOnline; @ApiModelProperty(value = '举办地址') private String address; @ApiModelProperty(value = '主办单位') private String organizer; @ApiModelProperty(value = '创建时间') private Date createTime;}

借助swagger注解标记接口

@Api(tags = '活动主体接口')@RestControllerpublic class ActivityWeb { @Resource private ActivityService activityService ; @ApiOperation('新增活动') @PostMapping('/activity') public Integer save (@RequestBody Activity activity){activityService.save(activity) ;return activity.getId() ; } @ApiOperation('主键查询') @GetMapping('/activity/{id}') public Activity getById (@PathVariable('id') Integer id){return activityService.getById(id) ; } @ApiOperation('修改活动') @PutMapping('/activity') public Boolean updateById (@RequestBody Activity activity){return activityService.updateById(activity) ; }}

SpringBoot2 集成测试组件的七种方法

通常来说,基于swagger注解标记接口类和方法上的入参和关键返参对象即可,这样可以避免再单独维护接口文档。

Swagger接口文档在开发的过程中更多是扮演文档的角色,真正使用swagger去调试的接口也常是一些增删改查的简单接口,这个工具也同样不适应于复杂流程的测试。

四、TestRestTemplate类

SpringBoot测试包中集成的测试API,需要依赖测试包,可以访问控制层接口,非常方便的完成交互过程:

Jar包依赖

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

使用案例

@RunWith(SpringRunner.class)@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)public class ActivityTest01 { protected static Logger logger = LoggerFactory.getLogger(ActivityTest01.class) ; @Resource private TestRestTemplate restTemplate; private Activity activity = null ; @Before public void before (){activity = restTemplate.getForObject('/activity/{id}', Activity.class,1);logger.info('n'+JSONUtil.toJsonPrettyStr(activity)); } @Test public void updateById (){if (activity != null){ activity.setCreateTime(new Date()); activity.setOrganizer('One商家'); restTemplate.put('/activity',activity);} } @After public void after (){activity = restTemplate.getForObject('/activity/{id}', Activity.class,1);logger.info('n'+JSONUtil.toJsonPrettyStr(activity));activity = null ; }}

在TestRestTemplate源码中可以发现,基于RestTemplate做封装,很多功能的实现都是调用RestTemplate方法。

用写代码的方式去实现接口测试,灵活度非常高,可以根据流程做定制开发,很适应于中等复杂的场景测试,这里为什么这样描述,下面对比Http请求再细说。

五、Http请求模式

通过模拟接口的Http请求实现的方式,目前来说个人感觉灵活的最高的方式,先看简单的案例:

@RunWith(SpringRunner.class)@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)public class ActivityTest03 { protected static Logger logger = LoggerFactory.getLogger(ActivityTest03.class) ; protected static String REQ_URL = '服务地址+端口'; @Test public void testHttp (){// 查询String getRes = HttpUtil.get(REQ_URL+'activity/1');logger.info('n {} ',JSONUtil.toJsonPrettyStr(getRes));Activity activity = JSONUtil.toBean(getRes, Activity.class) ;// 新增activity.setId(null);activity.setOrganizer('Http商家');String saveRes = HttpUtil.post(REQ_URL+'/activity',JSONUtil.toJsonStr(activity));logger.info('n {} ',saveRes);// 更新activity.setId(Integer.parseInt(saveRes));activity.setOrganizer('Put商家');String putRes = HttpRequest.put(REQ_URL+'/activity').body(JSONUtil.toJsonStr(activity)).execute().body();logger.info('n {} ',putRes); }}

这种方式对于复杂的业务流程来说非常好用,当然这里不排除个人习惯,在测试复杂流程的时候,一个简单方案:

用户信息:模拟http中token数据; 业务流程:通过数据获取包装参数模型; 独立服务管理,模拟并发场景; 根据执行过程生成分析数据结果;

对于复杂业务流程的测试,每个节点的模拟都具有一定的难度,通常在完整的流程中涉及到的服务和库表都是多个,并且请求链路复杂,基于一个灵活的自动化流程,去测试完整的链路,可以对效率有极大的提升。

六、Service层测试

针对服务层的测试手段,其本意在于业务实现的逻辑测试:

@RunWith(SpringRunner.class)@SpringBootTest(classes = Application.class)public class ActivityTest04 { protected static Logger logger = LoggerFactory.getLogger(ActivityTest04.class) ; @Autowired private ActivityService activityService ; @Test public void testService (){// 查询Activity activity = activityService.getById(1) ;// 新增activity.setId(null);activityService.save(activity) ;// 修改activity.setOrganizer('Ser商家');activityService.updateById(activity) ;// 删除activityService.removeById(activity.getId()) ; }}

该测试在实际的开发过程也并不常用,偶尔在于某个业务方法实现难度很大,用来针对性测试。

七、MockMvc方式

MockMvc同样是SpringBoot集成测试包提供的测试方式,通过对象的模拟,验证接口是否符合预期:

@AutoConfigureMockMvc@RunWith(SpringRunner.class)@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)public class ActivityTest02 { protected static Logger logger = LoggerFactory.getLogger(ActivityTest02.class) ; @Resource private MockMvc mockMvc ; private Activity activity = null ; @Before public void before () throws Exception {ResultActions resultAction = mockMvc.perform(MockMvcRequestBuilders.get('/activity/{id}',1)) ;MvcResult mvcResult = resultAction.andReturn() ;String result = mvcResult.getResponse().getContentAsString();activity = JSONUtil.toBean(result,Activity.class) ; } @Test public void updateById () throws Exception {activity.setId(null);activity.setCreateTime(new Date());activity.setOrganizer('One商家');ResultActions resultAction = mockMvc.perform(MockMvcRequestBuilders.post('/activity') .contentType(MediaType.APPLICATION_JSON) .content(JSONUtil.toJsonStr(activity))) ;MvcResult mvcResult = resultAction.andReturn() ;String result = mvcResult.getResponse().getContentAsString();activity.setId(Integer.parseInt(result));logger.info('result : {} ',result); } @After public void after () throws Exception {activity.setCreateTime(new Date());activity.setOrganizer('Update商家');ResultActions resultAction = mockMvc.perform(MockMvcRequestBuilders.put('/activity').contentType(MediaType.APPLICATION_JSON).content(JSONUtil.toJsonStr(activity))) ;MvcResult mvcResult = resultAction.andReturn() ;String result = mvcResult.getResponse().getContentAsString();logger.info('result : {} ',result); }}

对于这种Mock类型的测试,非常专业,通常个人使用极少,暂时没有Get到其精髓思想。

八、Mockito测试

Mock属于非常专业和标准的测试手段,需要依赖powermock包:

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

简单使用案例:

@RunWith(PowerMockRunner.class)@SpringBootTestpublic class ActivityTest05 { @Test public void testMock (){Set mockSet = PowerMockito.mock(Set.class);PowerMockito.when(mockSet.size()).thenReturn(10);int actual = mockSet.size();int expected = 15 ;Assert.assertEquals('返回值不符合预期',expected, actual); } @Test public void testTitle (){String expectTitle = 'Mock主题' ;Activity activity = PowerMockito.mock(Activity.class);PowerMockito.when(activity.getMockTitle()).thenReturn(expectTitle);String actualTitle = activity.getMockTitle();Assert.assertNotEquals('主题相符', expectTitle, actualTitle); }}

可以通过Mock方式,快速模拟出复杂的对象结构,以便构建测试方法,由于使用很少,同样个人暂时没Get到点。

九、源代码地址

GitHub·地址https://github.com/cicadasmile/middle-ware-parentGitEE·地址https://gitee.com/cicadasmile/middle-ware-parent

以上就是SpringBoot2 集成测试组件的七种方法的详细内容,更多关于SpringBoot2 集成测试组件的资料请关注好吧啦网其它相关文章!

标签: Spring
相关文章: