张家口网站建设制作,刘素云网站脱孝怎样做,郑州房产网二手房,网站建站平台系统JUnit 5 #xff08;JUnit Jupiter#xff09;已经存在了相当长的一段时间#xff0c;并且配备了许多功能。 但令人意外JUnit 5它不是一个默认的测试库相关#xff0c;当涉及到春节开机测试入门#xff1a;它仍然是JUnit 4.12 #xff0c;在2014年发布了回来#xff0c;… JUnit 5 JUnit Jupiter已经存在了相当长的一段时间并且配备了许多功能。 但令人意外JUnit 5它不是一个默认的测试库相关当涉及到春节开机测试入门它仍然是JUnit 4.12 在2014年发布了回来如果你考虑使用JUnit 5对你未来基于Spring启动项目然后这篇博客文章是给你的。 您将通过针对不同用例的Spring Boot测试示例了解基于Gradle和Maven的项目的基本设置。 源代码 可以在Github上找到本文的源代码 https : //github.com/kolorobot/spring-boot-junit5 。 从头开始设置项目 对于项目设置您将需要JDK 11或更高版本以及Gradle或Maven取决于您的偏好。 开始使用Spring Boot的最简单方法是使用https://start.spring.io上的Initializr。 选择的唯一依赖项是Spring Web 。 无论您在生成的项目中使用什么依赖项始终都包含测试依赖项 Spring Boot Starter Test 。 用Gradle构建 使用Initializr生成的Gradle构建的默认项目文件 gradle.build plugins { id org.springframework.boot version 2.1.8.RELEASE id io.spring.dependency-management version 1.0.8.RELEASE id java } group pl.codeleak.samples version 0.0.1-SNAPSHOT sourceCompatibility 11 repositories { mavenCentral() } dependencies { implementation org.springframework.boot:spring-boot-starter-web testImplementation org.springframework.boot:spring-boot-starter-test } 为了增加对JUnit 5支持我们需要排除旧的JUnit 4依赖性并包括JUnit 5 JUnit Jupiter依赖性 dependencies { implementation org.springframework.boot:spring-boot-starter-web testImplementation( org.springframework.boot:spring-boot-starter-test ) { exclude group: junit , module: junit } testCompile org.junit.jupiter:junit-jupiter:5.5.2 } test { useJUnitPlatform() testLogging { events passed , skipped , failed } } 用Maven构建 使用Initializr生成的Maven构建的默认项目文件 pom.xml ? xml version 1.0 encoding UTF-8 ? project modelVersion 4.0.0/ modelVersion parent groupId org.springframework.boot/ groupId artifactId spring-boot-starter-parent/ artifactId version 2.1.8.RELEASE/ version relativePath / !-- lookup parent from repository -- / parent groupId pl.codeleak.samples/ groupId artifactId spring-boot-junit5/ artifactId version 0.0.1-SNAPSHOT/ version name spring-boot-junit5/ name description Demo project for Spring Boot and JUnit 5/ description properties project.build.sourceEncoding UTF-8/ project.build.sourceEncoding java.version 11/ java.version / properties dependencies dependency groupId org.springframework.boot/ groupId artifactId spring-boot-starter-web/ artifactId / dependency dependency groupId org.springframework.boot/ groupId artifactId spring-boot-starter-test/ artifactId scope test/ scope / dependency / dependencies build plugins plugin groupId org.springframework.boot/ groupId artifactId spring-boot-maven-plugin/ artifactId / plugin / plugins / build / project 为了增加对JUnit 5支持我们需要排除旧的JUnit 4依赖性并包括JUnit 5 JUnit Jupiter依赖性 properties junit.jupiter.version 5.5.2/ junit.jupiter.version / properties dependencies dependency groupId org.springframework.boot/ groupId artifactId spring-boot-starter-web/ artifactId / dependency dependency groupId org.springframework.boot/ groupId artifactId spring-boot-starter-test/ artifactId scope test/ scope exclusions exclusion groupId junit/ groupId artifactId junit/ artifactId / exclusion / exclusions / dependency dependency groupId org.junit.jupiter/ groupId artifactId junit-jupiter/ artifactId version ${junit.jupiter.version}/ version scope test/ scope / dependency / dependencies 在测试类中使用JUnit 5 Initializr生成的测试包含自动生成的JUnit 4测试。 要应用JUnit 5我们需要更改导入并将JUnit 4替换为JUnit 5扩展。 我们还可以使类和测试方法包受到保护 import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; ExtendWith (SpringExtension. class ) SpringBootTest class SpringBootJunit5ApplicationTests { Test void contextLoads() { } } 提示如果您不熟悉JUnit 5请参阅我有关JUnit 5的其他文章 https : //blog.codeleak.pl/search/label/junit 5 运行测试 我们可以使用Maven Wrapper ./mvnw clean test或Gradle Wrapper ./gradlew clean test 。 源代码 请咨询此提交以获取与项目设置相关的更改。 具有单个REST控制器的示例应用程序 该示例应用程序包含一个具有三个端点的REST控制器 /tasks/{id} /tasks /tasks?title{title} 控制器的每个方法都在内部调用JSONPlaceholder –用于测试和原型制作的假在线REST API。 项目文件的结构如下 $ tree src/main/java src/main/java └── pl └── codeleak └── samples └── springbootjunit5 ├── SpringBootJunit5Application.java ├── config │ ├── JsonPlaceholderApiConfig.java │ └── JsonPlaceholderApiConfigProperties.java └── todo ├── JsonPlaceholderTaskRepository.java ├── Task.java ├── TaskController.java └── TaskRepository.java 它还具有以下静态资源 $ tree src/main/resources/ src/main/resources/ ├── application.properties ├── static │ ├── error │ │ └── 404 .html │ └── index.html └── templates TaskController将其工作委托给TaskRepository RestController class TaskController { private final TaskRepository taskRepository; TaskController(TaskRepository taskRepository) { this .taskRepository taskRepository; } GetMapping ( /tasks/{id} ) Task findOne( PathVariable Integer id) { return taskRepository.findOne(id); } GetMapping ( /tasks ) ListTask findAll() { return taskRepository.findAll(); } GetMapping (value /tasks , params title ) ListTask findByTitle(String title) { return taskRepository.findByTitle(title); } } TaskRepository由JsonPlaceholderTaskRepository实现该TaskRepository在内部使用RestTemplate来调用JSONPlaceholder https://jsonplaceholder.typicode.com 端点 public class JsonPlaceholderTaskRepository implements TaskRepository { private final RestTemplate restTemplate; private final JsonPlaceholderApiConfigProperties properties; public JsonPlaceholderTaskRepository(RestTemplate restTemplate, JsonPlaceholderApiConfigProperties properties) { this .restTemplate restTemplate; this .properties properties; } Override public Task findOne(Integer id) { return restTemplate .getForObject( /todos/{id} , Task. class , id); } // other methods skipped for readability } 通过JsonPlaceholderApiConfig配置应用程序该配置JsonPlaceholderApiConfig使用JsonPlaceholderApiConfigProperties绑定来自application.properties一些明智的属性 Configuration EnableConfigurationProperties (JsonPlaceholderApiConfigProperties. class ) public class JsonPlaceholderApiConfig { private final JsonPlaceholderApiConfigProperties properties; public JsonPlaceholderApiConfig(JsonPlaceholderApiConfigProperties properties) { this .properties properties; } Bean RestTemplate restTemplate() { return new RestTemplateBuilder() .rootUri(properties.getRootUri()) .build(); } Bean TaskRepository taskRepository(RestTemplate restTemplate, JsonPlaceholderApiConfigProperties properties) { return new JsonPlaceholderTaskRepository(restTemplate, properties); } } application.properties包含几个与JSONPlaceholder端点配置有关的属性 json-placeholder.root-urihttps: //jsonplaceholder.typicode.com json-placeholder.todo-find-all.sortid json-placeholder.todo-find-all.orderdesc json-placeholder.todo-find-all.limit 20 在此博客文章中了解有关ConfigurationProperties更多信息 https : //blog.codeleak.pl/2014/09/using-configurationproperties-in-spring.html 源代码 请咨询此提交以获取与应用程序源代码相关的更改。 创建Spring Boot测试 Spring Boot提供了许多支持测试应用程序的实用程序和注释。 创建测试时可以使用不同的方法。 在下面您将找到创建Spring Boot测试的最常见情况。 在随机端口上运行Web服务器的Spring Boot测试 ExtendWith (SpringExtension. class ) SpringBootTest (webEnvironment SpringBootTest.WebEnvironment.RANDOM_PORT) class TaskControllerIntegrationTest { LocalServerPort private int port; Autowired private TestRestTemplate restTemplate; Test void findsTaskById() { // act var task restTemplate.getForObject( http://localhost: port /tasks/1 , Task. class ); // assert assertThat(task) .extracting(Task::getId, Task::getTitle, Task::isCompleted, Task::getUserId) .containsExactly( 1 , delectus aut autem , false , 1 ); } } 在具有模拟依赖项的随机端口上运行Web服务器的Spring Boot测试 ExtendWith (SpringExtension. class ) SpringBootTest (webEnvironment SpringBootTest.WebEnvironment.RANDOM_PORT) class TaskControllerIntegrationTestWithMockBeanTest { LocalServerPort private int port; MockBean private TaskRepository taskRepository; Autowired private TestRestTemplate restTemplate; Test void findsTaskById() { // arrange var taskToReturn new Task(); taskToReturn.setId( 1 ); taskToReturn.setTitle( delectus aut autem ); taskToReturn.setCompleted( true ); taskToReturn.setUserId( 1 ); when(taskRepository.findOne( 1 )).thenReturn(taskToReturn); // act var task restTemplate.getForObject( http://localhost: port /tasks/1 , Task. class ); // assert assertThat(task) .extracting(Task::getId, Task::getTitle, Task::isCompleted, Task::getUserId) .containsExactly( 1 , delectus aut autem , true , 1 ); } } 带有模拟MVC层的Spring Boot测试 ExtendWith (SpringExtension. class ) SpringBootTest AutoConfigureMockMvc class TaskControllerMockMvcTest { Autowired private MockMvc mockMvc; Test void findsTaskById() throws Exception { mockMvc.perform(get( /tasks/1 )) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().json( {\id\:1,\title\:\delectus aut autem\,\userId\:1,\completed\:false} )); } } 具有模拟的MVC层和模拟的依赖项的Spring Boot测试 ExtendWith (SpringExtension. class ) SpringBootTest AutoConfigureMockMvc class TaskControllerMockMvcWithMockBeanTest { Autowired private MockMvc mockMvc; MockBean private TaskRepository taskRepository; Test void findsTaskById() throws Exception { // arrange var taskToReturn new Task(); taskToReturn.setId( 1 ); taskToReturn.setTitle( delectus aut autem ); taskToReturn.setCompleted( true ); taskToReturn.setUserId( 1 ); when(taskRepository.findOne( 1 )).thenReturn(taskToReturn); // act and assert mockMvc.perform(get( /tasks/1 )) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().json( {\id\:1,\title\:\delectus aut autem\,\userId\:1,\completed\:true} )); } } 带有模拟Web层的Spring Boot测试 ExtendWith (SpringExtension. class ) WebMvcTest Import (JsonPlaceholderApiConfig. class ) class TaskControllerWebMvcTest { Autowired private MockMvc mockMvc; Test void findsTaskById() throws Exception { mockMvc.perform(get( /tasks/1 )) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().json( {\id\:1,\title\:\delectus aut autem\,\userId\:1,\completed\:false} )); } } 具有模拟Web层和模拟依赖项的Spring Boot测试 ExtendWith (SpringExtension. class ) WebMvcTest class TaskControllerWebMvcWithMockBeanTest { Autowired private MockMvc mockMvc; MockBean private TaskRepository taskRepository; Test void findsTaskById() throws Exception { // arrange var taskToReturn new Task(); taskToReturn.setId( 1 ); taskToReturn.setTitle( delectus aut autem ); taskToReturn.setCompleted( true ); taskToReturn.setUserId( 1 ); when(taskRepository.findOne( 1 )).thenReturn(taskToReturn); // act and assert mockMvc.perform(get( /tasks/1 )) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().json( {\id\:1,\title\:\delectus aut autem\,\userId\:1,\completed\:true} )); } } 运行所有测试 我们可以使用Maven Wrapper ./mvnw clean test或Gradle Wrapper ./gradlew clean test运行所有./gradlew clean test 。 使用Gradle运行测试的结果 $ ./gradlew clean test Task :test pl.codeleak.samples.springbootjunit5.SpringBootJunit5ApplicationTests contextLoads() PASSED pl.codeleak.samples.springbootjunit5.todo.TaskControllerWebMvcTest findsTaskById() PASSED pl.codeleak.samples.springbootjunit5.todo.TaskControllerIntegrationTestWithMockBeanTest findsTaskById() PASSED pl.codeleak.samples.springbootjunit5.todo.TaskControllerWebMvcWithMockBeanTest findsTaskById() PASSED pl.codeleak.samples.springbootjunit5.todo.TaskControllerIntegrationTest findsTaskById() PASSED pl.codeleak.samples.springbootjunit5.todo.TaskControllerMockMvcTest findsTaskById() PASSED pl.codeleak.samples.springbootjunit5.todo.TaskControllerMockMvcWithMockBeanTest findsTaskById() PASSED BUILD SUCCESSFUL in 7s 5 actionable tasks: 5 executed 参考文献 https://docs.spring.io/spring-boot/docs/2.1.8.RELEASE/reference/html/boot-features-testing.html https://spring.io/guides/gs/testing-web/ https://github.com/spring-projects/spring-boot/issues/14736 翻译自: https://www.javacodegeeks.com/2019/09/spring-boot-testing-junit-5.html