[springboot一本通]-2

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

    MvcResult result = mockMvc.perform(

        MockMvcRequestBuilders

            .request(HttpMethod.POST, "/rest/articles")

            .contentType("application/json")

            .content(article)

    )

    .andExpect(MockMvcResultMatchers.status().isOk())  //HTTP:status 200

    .andExpect(MockMvcResultMatchers.jsonPath("$.data.author").value("zimug"))

    .andExpect(MockMvcResultMatchers.jsonPath("$.data.reader[0].age").value(18))

    .andDo(print())

    .andReturn();

    result.getResponse().setCharacterEncoding("UTF-8");

    log.info(result.getResponse().getContentAsString());



}

}




MockMvc对象有以下几个基本的方法:



*   perform : 模拟执行一个RequestBuilder构建的HTTP请求,会执行SpringMVC的流程并映射到相应的控制器Controller执行。

*   contentType:发送请求内容的序列化的格式,"application/json"表示JSON数据格式

*   andExpect: 添加RequsetMatcher验证规则,验证控制器执行完成后结果是否正确,或者说是结果是否与我们期望(Expect)的一致。

*   andDo: 添加ResultHandler结果处理器,比如调试时打印结果到控制台

*   andReturn: 最后返回相应的MvcResult,然后进行自定义验证/进行下一步的异步处理



> 上面的整个过程,我们都没有使用到Spring Context依赖注入、也没有启动tomcat web容器。整个测试的过程十分的轻量级,速度很快。



[]( )二、真实servlet容器环境下的测试

----------------------------------------------------------------------------



上面的测试执行速度非常快,但是有一个问题:它没有启动servlet容器和Spring 上下文,自然也就无法实现依赖注入(不支持@Resource和@AutoWired注解)。这就导致它在从控制层到持久层全流程测试中有很大的局限性。  

![在这里插入图片描述](https://img-blog.csdnimg.cn/d0637e48987a499c8220be6eec6075bb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a2X5q-N5ZOl5ZOl,size_20,color_FFFFFF,t_70,g_se,x_16)



换一种写法:看看有没有什么区别。在测试类上面额外加上这样两个注解,并且mockMvc对象使用@Resource自动注入,删掉Before注解及setUp函数。



@AutoConfigureMockMvc

@SpringBootTest

@ExtendWith(SpringExtension.class)




![在这里插入图片描述](https://img-blog.csdnimg.cn/39bf1f755b0e4c28b221d10dbace736b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a2X5q-N5ZOl5ZOl,size_20,color_FFFFFF,t_70,g_se,x_16)



启动测试一下,看看和之前有没有什么区别.  

![在这里插入图片描述](https://img-blog.csdnimg.cn/d3e885580be747e9806c381a65c44af8.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a2X5q-N5ZOl5ZOl,size_20,color_FFFFFF,t_70,g_se,x_16)



看到上面这个截图,是不是已经明白了!该测试方法真实的启动了一个tomcat容器、以及Spring 上下文,所以我们可以进行依赖注入(@Resource)。实现的效果和使用MockMvcBuilders构建MockMVC对象的效果是一样的,但是有一个非常明显的缺点:每次做一个接口测试,都会真实的启动一次servlet容器,Spring上下文加载项目里面定义的所有的Bean,导致执行过程很缓慢。



### []( )2.1 @SpringBootTest 注解



是用来创建Spring的上下文ApplicationContext,保证测试在上下文环境里运行。单独使用@SpringBootTest不会启动servlet容器。所以**只是使用SpringBootTest 注解,不可以使用@Resource和@Autowired等注解进行bean的依赖注入**。(准确的说是可以使用,但被注解的bean为null)。



### []( )2.2 @ExtendWith(@RunWith注解)



*   RunWith方法为我们构造了一个的Servlet容器运行运行环境,并在此环境下测试。然而为什么要构建servlet容器?因为使用了依赖注入,注入了MockMvc对象,而在上一个例子里面是我们自己new的。

*   而@AutoConfigureMockMvc注解,该注解表示mockMvc对象由spring 依赖注入构建,你只负责使用就可以了。这种写法是为了让测试在servlet容器环境下执行。



简单的说:**如果你单元测试代码使用了“依赖注入@Resource”就必须加上@ExtendWith,如果你不是手动new MockMvc对象就加上@AutoConfigureMockMvc**



> 实际上@SpringBootTest 注解注解已经包含了 @ExtendWith注解,如果使用了前者,可以忽略后者!



### []( )2.3 @Transactional



该注解加在方法上可以使单元测试进行事务回滚,以保证数据库表中没有因测试造成的垃圾数据,因此保证单元测试可以反复执行;  

但是笔者不建议这么做,使用该注解会破坏测试真实性。请参考这篇文章详细理解:  

[不要在 Spring Boot 集成测试中使用 @Transactional]( )



[]( )三、Mock测试

-----------------------------------------------------------------



### []( )3.1什么是Mock?



在面向对象程序设计中,模拟对象(英语:mock object,也译作模仿对象)是以可控的方式模拟真实对象行为的**假的对象**。比如:对象B依赖于对象A,但是A代码还没写是一个空类空方法不能用,我们来mock一个假的A来完成测试。



### []( )3.2 为什么要使用Mock?



![在这里插入图片描述](https://img-blog.csdnimg.cn/56487f2c75934695bed2e46e90949086.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a2X5q-N5ZOl5ZOl,size_20,color_FFFFFF,t_70,g_se,x_16)



> 在单元测试中,模拟对象可以模拟复杂的、真实的对象的行为, 如果真实的对象无法放入单元测试中,使用模拟对象就很有帮助。



在下面的情形,可能需要使用 **“模拟对象行为”** 来代替真实对象:



*   真实对象的行为是不确定的(例如,当前的时间或当前的温度);

*   真实对象很难搭建起来;

*   真实对象的行为很难触发(例如,网络错误);

*   真实对象速度很慢(例如,一个完整的数据库,在测试之前可能需要初始化);

*   真实的对象是用户界面,或包括用户界面在内;

*   真实的对象使用了回调机制;

*   真实对象可能还不存在(例如,其他程序员还为完成工作);

*   真实对象可能包含不能用作测试的信息(高度保密信息等)和方法。



### []( )3.3.场景实践



我们的保存文章的Controller方法,调用ArticleService的saveArticle进行文章的保存。  

![在这里插入图片描述](https://img-blog.csdnimg.cn/5fd292a6e2b741419ce8c3018543c51b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a2X5q-N5ZOl5ZOl,size_20,color_FFFFFF,t_70,g_se,x_16)



但是因为种种原因,这个接口目前没能实现(只有接口,代码如下)。比如说:另一个程序员暂时没完成工作,或者是机密内容实现,不能被用于测试环境。



public interface ArticleService {

public String saveArticle(Article article);

}




但是现在接口调用方找到我了,需要进行接口验证。怎么办?我们就可以使用Mock的方法,先Mock一个假的ArticleService,把接口验证完成。



@Slf4j

@AutoConfigureMockMvc

@SpringBootTest

@ExtendWith(SpringExtension.class)

public class ArticleRestControllerTest3 {

//mock对象

@Resource

private MockMvc mockMvc;



@MockBean

private ArticleService articleService;



//测试方法

@Test

public void saveArticle() throws Exception {



    String article = "{\n" +

            "    \"id\": 1,\n" +

            "    \"author\": \"zimug\",\n" +

            "    \"title\": \"手摸手教你开发spring boot\",\n" +

            "    \"content\": \"c\",\n" +

            "    \"createTime\": \"2017-07-16 05:23:34\",\n" +

            "    \"reader\":[{\"name\":\"zimug\",\"age\":18},{\"name\":\"kobe\",\"age\":37}]\n" +

            "}";



    ObjectMapper objectMapper = new ObjectMapper();

    Article articleObj = objectMapper.readValue(article,Article.class);



    //打桩

    when(articleService.saveArticle(articleObj)).thenReturn("ok");



    MvcResult result = mockMvc.perform(

            MockMvcRequestBuilders.request(HttpMethod.POST, "/rest/articles")

            .contentType("application/json").content(article))

            .andExpect(MockMvcResultMatchers.jsonPath("$.data").value("ok"))

            .andDo(print())

            .andReturn();

    

    result.getResponse().setCharacterEncoding("UTF-8");

    log.info(result.getResponse().getContentAsString());



}

}




### []( )@MockBean



可以用MockBean伪造模拟一个Service ,如上图中的MockBean。



大家注意上文代码中,打了一个桩



when(articleService.saveArticle(articleObj)).thenReturn(“ok”);




也就是告诉测试用例程序,当你调用articleService.saveArticle(articleObj)方法的时候,不要去真的调用这个方法,直接返回一个结果(“ok”)就好了。



.andExpect(MockMvcResultMatchers.jsonPath(“$.data”).value(“ok”))




测试用例跑通了,期望结果andExpect:ok与实际结果thenReturn(“ok”)一致。表示程序真正的去执行了MockBean的模拟行为,而不是调用真实对象的方法。



[]( )四、轻量级测试

----------------------------------------------------------------



在ExtendWith的AutoConfigureMockMvc注解的共同作用下,启动了SpringMVC的运行容器,并且把项目中所有的@Bean全部都注入进来。把所有的bean都注入进来是不是很臃肿?这样会拖慢单元测试的效率。如果我只是想测试一下控制层Controller,怎么办?或者说我只想具体到测试一下ArticleRestController,怎么办?要把应用中所有的bean都注入么?有没有轻量级的解决方案?一定是有的。



@ExtendWith(SpringExtension.class)

@WebMvcTest(ArticleController.class)

//@SpringBootTest




#### []( )使用@WebMvcTest替换@SpringBootTest



*   @SpringBootTest注解告诉SpringBoot去寻找一个主配置类(例如带有@SpringBootApplication的配置类),并使用它来启动Spring应用程序上下文。SpringBootTest加载完整的应用程序并注入所有可能的bean,因此速度会很慢。

    

*   @WebMvcTest注解主要用于controller层测试,只覆盖应用程序的controller层,@WebMvcTest(ArticleController.class)只加载ArticleController这一个Bean用作测试。所以WebMvcTest要快得多,因为我们只加载了应用程序的一小部分。

    



[]( )五、MockMvc更多的用法总结

-------------------------------------------------------------------------



//模拟GET请求:

mockMvc.perform(MockMvcRequestBuilders.get(“/user/{id}”, userId));

//模拟Post请求:

mockMvc.perform(MockMvcRequestBuilders.post(“uri”, parameters));

//模拟文件上传:

mockMvc.perform(MockMvcRequestBuilders.multipart(“uri”).file(“fileName”, “file”.getBytes(“UTF-8”)));

//模拟session和cookie:

mockMvc.perform(MockMvcRequestBuilders.get(“uri”).sessionAttr(“name”, “value”));

mockMvc.perform(MockMvcRequestBuilders.get(“uri”).cookie(new Cookie(“name”, “value”)));

//设置HTTP Header:

mockMvc.perform(MockMvcRequestBuilders

                    .get("uri", parameters)

                    .contentType("application/x-www-form-urlencoded")

                    .accept("application/json")

                    .header("", ""));



 



  



本文转自 [https://zimug.blog.csdn.net/article/details/122892275]( ),如有侵权,请联系删除。


![img](https://img-blog.csdnimg.cn/img_convert/cc8d6f0a1a74ade010302ad5e5ba68af.png)
![img](https://img-blog.csdnimg.cn/img_convert/3e3d1971aec3a08f82b3bca74aa9d723.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618631832)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

                .header("", ""));





本文转自 https://zimug.blog.csdn.net/article/details/122892275,如有侵权,请联系删除。

[外链图片转存中…(img-Ko8dcaUV-1715898523102)]
[外链图片转存中…(img-wd8245fn-1715898523102)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Springboot CAS-Client 是一个基于Springboot框架集成CAS(Central Authentication Service)的客户端。 CAS是一种单点登录(Single Sign-On)协议,它允许用户在一次登录后就能够访问多个应用,而无需重新认证。 Springboot CAS-Client 的作用是充当CAS服务端和应用系统之间的中间件,它负责向CAS服务端发送认证请求,并根据认证结果来管理用户的登录状态。 为了集成CAS,我们首先需要在Springboot项目中引入相应的依赖,例如spring-boot-starter-web和spring-boot-starter-security。接着,我们需要配置CAS服务端的地址信息,包括CAS服务端的登录URL、登出URL以及验证票据的URL等。 在Springboot CAS-Client中,我们也可以自定义一些过滤器和拦截器来实现相关的功能。例如,我们可以编写一个CAS认证过滤器来拦截所有的请求,并判断用户的登录状态。如果用户未登录,则跳转到CAS服务端进行认证;如果用户已登录,则直接放行请求。此外,我们还可以编写一个CAS登出拦截器来处理用户的登出请求,并在登出完成后将用户重定向到指定的页面。 总的来说,Springboot CAS-Client 提供了一个简洁、灵活的方式来集成CAS协议,使得我们的Springboot应用能够享受到单点登录带来的便利。过它,我们可以轻松地实现用户认证、登录状态管理以及注销等功能,提升用户体验并提高开发效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值