Spring Boot Web Slice测试–示例

春天开机推出 测试切片而回,它已经采取了一些时间来解决它我的头,并探讨一些细微的差别。

背景

使用此功能的主要原因是减少样板。 考虑一个看起来像这样的控制器,仅适用于使用Kotlin编写的各种控制器。

@RestController
@RequestMapping("/users")
class UserController(private val userRepository: UserRepository,private val userResourceAssembler: UserResourceAssembler) {@GetMappingfun getUsers(pageable: Pageable, pagedResourcesAssembler: PagedResourcesAssembler<User>): PagedResources<Resource<User>> {val users = userRepository.findAll(pageable)return pagedResourcesAssembler.toResource(users, this.userResourceAssembler)}@GetMapping("/{id}")fun getUser(id: Long): Resource<User> {return Resource(userRepository.findOne(id))}
}

用于测试此控制器的传统Spring Mock MVC测试将遵循以下原则:

@RunWith(SpringRunner::class)
@WebAppConfiguration
@ContextConfiguration
class UserControllerTests {lateinit var mockMvc: MockMvc@Autowiredprivate val wac: WebApplicationContext? = null@Beforefun setup() {this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build()}@Testfun testGetUsers() {this.mockMvc.perform(get("/users").accept(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk)}@EnableSpringDataWebSupport@EnableWebMvc@Configurationclass SpringConfig {@Beanfun userController(): UserController {return UserController(userRepository(), UserResourceAssembler())}@Beanfun userRepository(): UserRepository {val userRepository = Mockito.mock(UserRepository::class.java)given(userRepository.findAll(Matchers.any(Pageable::class.java))).willAnswer({ invocation ->val pageable = invocation.arguments[0] as PageablePageImpl(listOf(User(id = 1, fullName = "one", password = "one", email = "one@one.com"),User(id = 2, fullName = "two", password = "two", email = "two@two.com")), pageable, 10)})return userRepository}}
}

设置这样的测试涉及很多仪式-理解Web环境的Web应用程序上下文被引入,需要创建设置Spring MVC环境的配置,以及满足测试框架需求的MockMvc在每次测试之前进行设置。

网页切片测试

与以前的测试相比,Web Slice测试要简单得多,它专注于测试控制器并隐藏了许多样板代码:

@RunWith(SpringRunner::class)
@WebMvcTest(UserController::class)
class UserControllerSliceTests {@Autowiredlateinit var mockMvc: MockMvc@MockBeanlateinit var userRepository: UserRepository@SpyBeanlateinit var userResourceAssembler: UserResourceAssembler@Testfun testGetUsers() {this.mockMvc.perform(get("/users").param("page", "0").param("size", "1").accept(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk)}@Beforefun setUp(): Unit {given(userRepository.findAll(Matchers.any(Pageable::class.java))).willAnswer({ invocation ->val pageable = invocation.arguments[0] as PageablePageImpl(listOf(User(id = 1, fullName = "one", password = "one", email = "one@one.com"),User(id = 2, fullName = "two", password = "two", email = "two@two.com")), pageable, 10)})}
}

它的工作方式是创建一个Spring Application上下文,但过滤掉与Web层无关的所有内容,并仅加载已传递到@WebTest批注中的控制器。 控制器需要的任何依赖关系都可以作为模拟注入。

涉及到一些细微差别,例如,如果我想自己注入某个字段,则可以使用自定义的Spring Configuration进行测试,对于测试,可以使用内部带有@TestConfiguration注释的静态类来完成。以下方式:

@RunWith(SpringRunner::class)
@WebMvcTest(UserController::class)
class UserControllerSliceTests {@Autowiredlateinit var mockMvc: MockMvc@Autowiredlateinit var userRepository: UserRepository@Autowiredlateinit var userResourceAssembler: UserResourceAssembler@Testfun testGetUsers() {this.mockMvc.perform(get("/users").param("page", "0").param("size", "1").accept(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk)}@Beforefun setUp(): Unit {given(userRepository.findAll(Matchers.any(Pageable::class.java))).willAnswer({ invocation ->val pageable = invocation.arguments[0] as PageablePageImpl(listOf(User(id = 1, fullName = "one", password = "one", email = "one@one.com"),User(id = 2, fullName = "two", password = "two", email = "two@two.com")), pageable, 10)})}@TestConfigurationclass SpringConfig {@Beanfun userResourceAssembler(): UserResourceAssembler {return UserResourceAssembler()}@Beanfun userRepository(): UserRepository {return mock(UserRepository::class.java)}}}

来自“ TestConfiguration”的Bean将添加到Slice测试所依赖的配置中,并且不会完全替换它。

另一方面,如果我想重写带注释的主“ @SpringBootApplication”主类的加载,则可以显式传递一个Spring Configuration类,但要注意的是,我现在必须负责所有相关的加载工作。 Spring Boot具有我自己的功能(启用自动配置,适当的扫描等),因此可以通过以下方式围绕它来显式批注Spring Boot应用程序的配置:

@RunWith(SpringRunner::class)
@WebMvcTest(UserController::class)
class UserControllerExplicitConfigTests {@Autowiredlateinit var mockMvc: MockMvc@Autowiredlateinit var userRepository: UserRepository@Testfun testGetUsers() {this.mockMvc.perform(get("/users").param("page", "0").param("size", "1").accept(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk)}@Beforefun setUp(): Unit {given(userRepository.findAll(Matchers.any(Pageable::class.java))).willAnswer({ invocation ->val pageable = invocation.arguments[0] as PageablePageImpl(listOf(User(id = 1, fullName = "one", password = "one", email = "one@one.com"),User(id = 2, fullName = "two", password = "two", email = "two@two.com")), pageable, 10)})}@SpringBootApplication(scanBasePackageClasses = arrayOf(UserController::class))@EnableSpringDataWebSupportclass SpringConfig {@Beanfun userResourceAssembler(): UserResourceAssembler {return UserResourceAssembler()}@Beanfun userRepository(): UserRepository {return mock(UserRepository::class.java)}}}

但是要注意的是,现在其他测试可能最终会找到这种不理想的内部配置!因此,我的学习一直依赖于最低限度的最小切片测试,如果需要,可以使用@TestConfiguration对其进行扩展。

我在github仓库中有一些更详细的代码示例,其中包含一些可用的示例。

翻译自: https://www.javacodegeeks.com/2017/06/spring-boot-web-slice-test-sample.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/349736.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DECODE函数

DECODE函数相当于一条件语句(IF),它将输入数值与函数中的参数列表相比较&#xff0c;根据输入值返回一个对应值。函数的参数列表是由若干数值及其对应结果值组成的若干序偶形式。当然&#xff0c;如果未能与任何一个实参序偶匹配成功&#xff0c;则函数也有默认的返回值。区别于…

多线程练习

写两个线程&#xff0c;其中一个线程打印1-52&#xff0c;另一个线程打印A-Z&#xff0c;打印顺序应该是12A34B56C......5152Z。 该习题需要用到多线程通信的知识。 思路分析&#xff1a; 把打印数字的线程称为线程N&#xff0c;打印字母的线程称为线程L. 1.线程N完成打印后&am…

java jee curd_Java / JEE中的有效日志记录–映射的诊断上下文

java jee curd这一切始于当我和一位同事坐在一起解决一些应用程序问题时&#xff0c;当我注意到一些有趣的事情时。 他正在合并代码&#xff0c;我的眼睛吸引了此类“ org.apache.log4j.MDC”的注意。 这导致了以下发现&#xff1a; 什么是MDC&#xff1f; MDC代表“ 映射诊断…

Learning Cocos2d-x for WP8(7)——让Sprite动起来

C#(wp7)兄弟篇Learning Cocos2d-x for XNA&#xff08;7&#xff09;——让Sprite动起来 本讲将详细介绍Cocos2d-x游戏中动画Animate的创建方式&#xff0c;通过逐帧数组播放动画和创建动画集合播放动画&#xff0c;比较两者的异同&#xff0c;让Sprite动起来。 工程文件&#…

GWT的渐进式Web应用程序配方

渐进或不渐进… 如果您一段时间以来一直在设计或开发Web应用程序&#xff0c;那么您可能会遇到无数次“渐进式Web应用程序”一词&#xff0c;并且在未来几年内可能会这样做。 您可能想知道PWA的确切定义是什么&#xff0c;如何识别PWA&#xff0c;以及如何构建PWA。 根据字典&a…

问题 1047: [编程入门]报数问题

题目描述有n人围成一圈&#xff0c;顺序排号。从第1个人开始报数&#xff08;从1到3报数&#xff09;&#xff0c;凡报到3的人退出圈子&#xff0c;问最后留下的是原来的第几号的那位。输入初始人数n输出最后一人的初始编号样例输入3 样例输出2分析&#xff1a;因为每次报3都会…

NOIP模拟测试17「入阵曲·将军令·星空」

入阵曲 题解 应用了一种美妙移项思想&#xff0c; 我们先考虑在一维上的做法 维护前缀和$(sum[r]-sum[l-1])\%k0$可以转化为 $sum[r]\% ksum[l-1]\%k$开个桶维护一下即可 然后拓展到二维上 把两行之间所有行拍扁看作一维上的区间&#xff0c; 我们枚举两行和行之间所有列开个桶…

理解sizeof

1、sizeof返回的是字节个数&#xff0c;内存编址的最小单元是字节。因此&#xff0c;空对象&#xff0c;bool值占用的内存也是一个字节。 2、可以对哪些东西求sizeof ? a、对象和类型。如int a; sizeof(a)&#xff0c; sizeof(int)&#xff0c;二者是等价的。同一类型的对象&a…

java 分析java死锁_Java死锁示例–如何分析死锁情况

java 分析java死锁死锁是两个线程或多个线程永远被阻塞的编程情况&#xff0c;这种情况发生在至少两个线程和两个或更多资源的情况下。 在这里&#xff0c;我编写了一个简单的程序&#xff0c;它将导致死锁情况&#xff0c;然后我们将看到如何对其进行分析。 Java死锁示例 pac…

insert 多条数据 并且具有唯一标识符

DECLARE COUNT INT DECLARE NAME NVARCHAR(10) SET COUNT0 WHILE COUNT<1000 BEGIN SET NAMESYSTEMCAST(COUNT AS NVARCHAR(10)) INSERT INTO dbo.users VALUES (NEWID(),NAME,123123COUNT,DATEADD(DAY,COUNT,2012-12-12),GETDATE()) SET COUNT COUNT 1 END 转载于:http…

Java Message System简介

Java消息系统 在本文中&#xff0c;我将讨论面向消息的中间件 &#xff08;MOM&#xff09;以及JMS如何在Enterprise Java中实现它。 另外&#xff0c;我将讨论适合JMS使用的典型用例以及用于讨论消息传递解决方案的不同术语&#xff0c;例如Publisher / Sender &#xff0c; D…

FLV协议5分钟入门浅析

FLV协议简介 FLV&#xff08;Flash Video&#xff09;是一种流媒体格式&#xff0c;因其体积小、协议相对简单&#xff0c;很快便流行开来&#xff0c;并得到广泛的支持。 常见的HTTP-FLV直播协议&#xff0c;就是使用HTTP流式传输通过FLV封装的音视频数据。对想要了解HTTP-FLV…

问题 1049: [编程入门]结构体之时间设计

题目描述定义一个结构体变量&#xff08;包括年、月、日&#xff09;。计算该日在本年中是第几天&#xff0c;注意闰年问题。输入年月日输出当年第几天样例输入2000 12 31 样例输出366 import java.util.Scanner; public class Main{ public static void main(String args[]){ …

反序列化 jackson_使用Jackson和Super类型令牌的Json反序列化

反序列化 jacksonDatatables是一个jquery插件&#xff0c;用于显示表格信息–它可以增强简单的表或可以使用基于AJAX的数据并以表格形式显示信息。 数据表要​​求来自服务器的数据遵循特定的JSON格式才能在屏幕上显示。 考虑要显示Member实体列表的情况&#xff0c;那么Membe…

NOIP模拟测试18「引子·可爱宝贝精灵·相互再归的鹅妈妈」

待补 引子 题解 大模拟&#xff0c;注意细节 代码1 #include<bits/stdc.h> using namespace std; int n,m;char a[1005][1005];bool vst[1005][1005]; void solve(int na,int nb) {int ina,jnb,now0;while(1){j;if(a[na][j])break;}while(1){i;if(a[i][nb])break;}for(in…

GC解释:收集器概述

当前版本的HotSpot JVM包括三种类型的垃圾收集器&#xff1a; –串行收集器 –并行收集器 –多数同时收集者 它们都是世代的&#xff0c;这意味着它们利用了堆的划分方式 。 垃圾收集器负责三个主要操作&#xff1a; –查找不再使用的对象 –释放这些对象之后的内存 –…

数据结构之排序五:选择排序

def selectedSort(myList):#获取list的长度length len(myList)#一共进行多少轮比较for i in range(0,length-1):#默认设置最小值得index为当前值smallest i#用当先最小index的值分别与后面的值进行比较,以便获取最小indexfor j in range(i1,length):#如果找到比当前值小的ind…

C#代码规范

1. 引言 本文是一套面向C# programmer 和C# developer 进行开发所应遵循的开发规范。 按照此规范来开发C#程序可带来以下益处&#xff1a; 代码的编写保持一致性&#xff0c; 提高代码的可读性和可维护性&#xff0c; 在团队开发一个项目的情况下&a…

谷歌guava_使用Google Guava进行馆藏创建和不变性

谷歌guava因此&#xff0c;我想看看番石榴提供的一些集合创建模式&#xff0c;以及它提供的某些不可变集合类型。 如果您没有看过我以前的文章&#xff0c;则可能要从这里开始&#xff1a; 番石榴第1部分– MultiMaps 番石榴第2部分– BiMaps 番石榴第3部分–多组 Guava的…

问题 1051: [编程入门]结构体之成绩统计2

题目描述有N个学生&#xff0c;每个学生的数据包括学号、姓名、3门课的成绩&#xff0c;从键盘输入N个学生的数据&#xff0c;要求打印出3门课的总平均成绩&#xff0c;以及最高分的学生的数据&#xff08;包括学号、姓名、3门课成绩&#xff09;输入学生数量N占一行每个学生的…