junit

postman

swagger

对啥进行测试

对方法进行测试

对路径接口进行测试

对路径接口进行测试

什么时候用

每修改一个方法进行测试,你不可能所有方法写完再用postman进行测试吧

就是一个完整的流程测试

也是一个完整的流程测试

侧重点

对方法进行测试

有其他很多强大的测试功能,但我们开发用到的也只是基本测试

他其实更注重于接口文档,但是对于基本的测试已经足够了

Junit

安装插件

生成测试

之后进入你想测试的方法的类中,按alt+insert,点击test

 @SpringBootTest
 class CollectionsControllerTest {
 ​
     @Autowired
     CollectionsController collectionsController;
 ​
     String name;
 ​
     @BeforeEach
     void setUp() {
         System.out.println("测试开始");
         name = "Ned";
     }
 ​
     @AfterEach
     void tearDown() {
         System.out.println("测试结束");
     }
 ​
     @Test
     void getByName() {
 ​
         Characters ned = collectionsController.getByName(name);
         System.out.println(ned);
 ​
     }
 }

@SpringBootTest 是 Spring Boot 提供的一个注解,用于启动 Spring Boot 的测试上下文框架。它会加载 Spring Boot 的配置,并启动一个完整的 Spring 应用程序上下文,以便在测试中使用 Spring 的各种功能,例如依赖注入、自动配置等。

比如你想想,为什么可以单独测试一个方法呢,不用像postman那样全流程呢,就是这个的功劳。

@BeforeEach就是在@Test之前执行的,注意这里是成员变量,Test方法里可以调用

 String name;
 ​
 @BeforeEach
 void setUp() {
     System.out.println("测试开始");
     name = "Ned";
 }

这里是局部变量,test不可以用,主要是定义的位置不一样

 @BeforeEach
 void setUp() {
     System.out.println("测试开始");
     String name; = "Ned";
 }

而且,这里所有的测试参数需要自己构造!!!

postman

界面非常直观,操作也很简单

主要难点应该在于理解不同的请求方法和请求参数的理解

请求方法:

  1. Get

  2. Post

  3. Update

  4. Delete

请求参数:

  1. 查询参数(Query Parameters)

  2. 路径参数(Path Parameters)

  3. 请求体参数(Body Parameters)

查询

Get+Query

Get就是查询,对应最频繁的参数是查询参数

这里注意,1是@GetMapping的格式。2是@RequestParam对应Query

Get+Path

这里注意GetMapping和@PathVariable

Post+Body

注意是@PostMapping和@RequestBody

3者区别

get+query是最常用的,比如一般的分页查询,条件查询都是用他。

那你可能想:get+path那是干嘛的呢?

是用于获取唯一资源的,比如获取某人的所有信息。

可能又想:get+query也可以实现这一功能啊?为什么不用这个

只能说,这是一种约定俗成的规范,可以理解为唯一路径对应唯一资源

那post+body为啥也拿来做查询啊,get+query不是够了嘛

post+body是用于参数非常非常复杂的情况(一般传JSON和表格两种进来),query适合几个查询条件

新增

一般是post+Body

更新

一般是put+body

新增和更新有啥关系嘛,都是传入一个body进来,而且真正的新增和更新的区分是在sql里吧,与方法无关

怎么说呢,这区分就是一种规范。

put方法在后面的处理逻辑中必须保证是幂等的(靠逻辑来实现。即update)

post则不是幂等的(即insert)

  • 对于 POST 请求,Mapper 可能会包含一个 insert 语句来添加新记录。

  • 对于 PUT 请求,Mapper 可能会包含一个 update 语句来更新现有记录。

删除

一般是delete+path

那批量删除怎么办呢?

场景

推荐方案

示例

少量 ID 删除

DELETE + 查询参数

DELETE /users?ids=1,2,3

大量 ID 或复杂条件

POST + 自定义路径 + 请求体

POST /users/batch-delete(Body: [1,2,3]

swagger

启动

swagger是一种规范,之前我们使用SpringFox,但他现在已经停止维护了,所以现在我们使用SpringDoc。SpringFox和SpringDoc都是去实现swagger这个规范。

         <dependency>
             <groupId>org.springdoc</groupId>
             <artifactId>springdoc-openapi-ui</artifactId>
             <version>1.6.14</version>
         </dependency>

现在只要加这个就行了,可以啊,不像以前那么麻烦了

启动然后访问http://localhost:8081/swagger-ui/index.html即可

注解

注解

含义

@Tag

用在controller类上,描述此controller的信息

@Operation

用在controller的方法里,描述此api的信息

@Parameter

用在controller方法里的参数上,描述参数信息

@Parameters

用在controller方法里的参数上

@Schema

用于Entity,以及Entity的属性上

@ApiResponse

用在controller方法的返回值上

@ApiResponses

用在controller方法的返回值上

@Hidden

用在各种地方,用于隐藏其api

日常我们最常用的就是 @Tag @Opeartion 这两个

界面

如果只有一个业务分类

 @Configuration
 public class SpringDocConfig {
     
     @Bean
     public OpenAPI myOpenAPI() {
         return new OpenAPI()
                 .info(new Info()
                         .title("程序员API")
                         .description("程序员的大本营")
                 );
     }
 ​
 }

但是如果有两个业务分类,例如商家端和客户端

 @Configuration
 public class SpringDocConfig {
 ​
     @Bean
     public OpenAPI myOpenAPI() {
         return new OpenAPI()
                 .info(new Info()
                         .title("程序员API")
                         .description("程序员的大本营")
                 );
     }
 ​
     @Bean
     public GroupedOpenApi publicApiGroup() {
         return GroupedOpenApi.builder()
                 .group("Public API")
                 .pathsToMatch("/api/public/**")
                 .addOpenApiCustomiser(openApi -> openApi.info(new Info().title("客户").description("客户")))
                 .build();
     }
 ​
     @Bean
     public GroupedOpenApi adminApiGroup() {
         return GroupedOpenApi.builder()
                 .group("Admin API")
                 .pathsToMatch("/api/admin/**")
                 .addOpenApiCustomiser(openApi -> openApi.info(new Info().title("商家").description("商家")))
                 .build();
     }
 ​
 }
 ​

其余和postman一致

比较是偷走幸福的小偷