如何使用RestTemplate测试接口

如何使用RestTemplate测试接口

RestTemplate位于org.springframework.web.client包中,它是一个执行HTTP请求的同步客户端,在诸如JDK的HttpURLConnection,Apache的HttpComponents等底层HTTP客户端上刚开一个简单的模板方法API。

我们可以编写单元测试,使用RestTemplate模拟客户端发送HTTP请求,来测试RETSful接口。

测试的Controller类:

package com.vk.ch09.controller;

import com.vk.ch09.model.Article;
import com.vk.ch09.result.BaseResult;
import com.vk.ch09.result.DataResult;
import com.vk.ch09.util.HttpStatusMap;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;

@RestController
@RequestMapping("/articles")
public class ArticleController {

    static List<Article> articles = new ArrayList<>();

    static {
        articles.add(new Article(1, "《Spring Boot 无难事》"));
        articles.add(new Article(2, "《Java 无难事》"));
        articles.add(new Article(3, "《Vue.js 3.0 从入门到实战》"));
    }

    // 保存新的文章
    @PostMapping
    public ResponseEntity<BaseResult> saveArticle(@RequestBody Article article) {
        articles.add(article);
        System.out.println(article);
        BaseResult result = new BaseResult(HttpStatusMap.get(HttpStatus.OK), "保存成功");
        return ResponseEntity.ok(result);
    }

    // 根据ID查找文章
    @GetMapping("/{id}")
    public ResponseEntity<BaseResult> getArticleById(@PathVariable Integer id) {
        Optional<Article> optionalArticle = articles.stream().filter(art -> art.getId().equals(id)).findFirst();

        try {
            Article article = optionalArticle.get();
            DataResult result = new DataResult();
            result.setCode(HttpStatusMap.get(HttpStatus.OK));
            result.setMsg("成功");
            result.setData(article);
            return ResponseEntity.ok(result);
        } catch (NoSuchElementException e) {
            BaseResult result = new BaseResult(HttpStatusMap.get(HttpStatus.BAD_REQUEST), "参数不合法");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
        }
    }

    // 返回所有文章数据
    @GetMapping
    public ResponseEntity<DataResult<List<Article>>> getAllArticles() {
        DataResult result = new DataResult();
        result.setCode(HttpStatusMap.get(HttpStatus.OK));
        result.setMsg("成功");
        result.setData(articles);
        return ResponseEntity.ok(result);
    }

    // 修改文章
    @PutMapping
    public ResponseEntity<BaseResult> updateArticle(@RequestBody Article article) {
        Optional<Article> opArticle = articles.stream()
                .filter(art -> art.getId() == article.getId())
                .findFirst();

        try {
            Article updatedArticle = opArticle.get();
            BeanUtils.copyProperties(article, updatedArticle);
            System.out.println(articles);
            BaseResult result = new BaseResult(HttpStatusMap.get(HttpStatus.OK), "修改成功");
            return ResponseEntity.ok(result);
        } catch (NoSuchElementException e) {
            BaseResult result = new BaseResult(HttpStatusMap.get(HttpStatus.BAD_REQUEST), "参数不合法");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
        }
    }

    // 根据ID删除文章
    @DeleteMapping("/{id}")
    public ResponseEntity<BaseResult> deleteArticle(@PathVariable Integer id) {
        Optional<Article> opArticle = articles.stream()
                .filter(art -> art.getId() == id).findFirst();
        try {
            Article article = opArticle.get();
            articles.remove(article);
            System.out.println(articles);
            BaseResult result = new BaseResult(HttpStatusMap.get(HttpStatus.OK), "删除成功");
            return ResponseEntity.ok(result);
        } catch (NoSuchElementException e) {
            BaseResult result = new BaseResult(HttpStatusMap.get(HttpStatus.BAD_REQUEST), "参数不合法");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
        }
    }
}

用于测试的ArticleControllerTest类:

package com.vk.ch09.controller;

import com.vk.ch09.model.Article;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class ArticleControllerTest {

    @Autowired
    private RestTemplateBuilder restTemplateBuilder;

    @Test
    void saveArticle() {
        RestTemplate client = restTemplateBuilder.build();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        Article article = new Article(4, "《VC++ 深入详解》");
        HttpEntity<Article> entity = new HttpEntity<Article>(article, headers);

        // postForObject()方法返回响应正文。
        // 如果需要返回整个响应实体,可以调用postForEntity()方法
        String body = client.postForObject("http://localhost:8080/articles", entity, String.class);
        System.out.println("body = " + body);
    }

    @Test
    void getArticleById() {
        RestTemplate client = restTemplateBuilder.build();
        // RESTful接口以JSON格式来承载数据,返回的是JSON串,因此类型参数指定String类型
        ResponseEntity<String> entity = client.getForEntity("http://localhost:8080/articles/{id}", String.class, 1);
        System.out.println(entity.getBody());
    }

    @Test
    void getAllArticles() {
        RestTemplate client = restTemplateBuilder.build();
        // 如果只需要响应正文,可以调用getForObject()方法
        String body = client.getForObject("http://localhost:8080/articles",
                String.class);
        System.out.println(body);
    }

    @Test
    void updateArticle() {
        RestTemplate client = restTemplateBuilder.build();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        Article article = new Article(1, "《VC++深入详解》");
        HttpEntity<Article> entity = new HttpEntity<Article>(article,headers);
        // put()方法没有返回值,如果需要接收响应消息,可以调用exchange方法。
        //client.put("http://localhost:8080/articles", entity);

        ResponseEntity<String> responseEntity = client.exchange(
                "http://localhost:8080/articles",
                HttpMethod.PUT,
                entity,
                String.class);
        System.out.println(responseEntity.getBody());
    }

    @Test
    void deleteArticle() {
        RestTemplate client = restTemplateBuilder.build();
        // delete()方法没有返回值,如果需要接收响应消息,可以调用exchange方法。
        //client.delete("http://localhost:8080/articles/{id}", 1);

        ResponseEntity<String> responseEntity = client.exchange(
                "http://localhost:8080/articles/{id}",
                HttpMethod.DELETE,
                null,
                String.class,
                1);
        System.out.println(responseEntity.getBody());
    }
}

先运行项目,然后运行各个测试方法以对接口进行测试。记得在ArticleControllerTest类加上@SpringBootTest注解

——出自《详解Spring Boot 从入门到企业级开发实战》 孙鑫 著

你可能感兴趣的:(SpringMVC,后端,SpringBoot,spring,spring,boot,后端,单元测试)