【单元测试】Controller、Service、Repository 层的单元测试
创始人
2024-11-05 17:11:08
0

Controller、Service、Repository 层的单元测试

  • 1.Controller 层的单元测试
    • 1.1 创建一个用于测试的控制器
    • 1.2 编写测试
  • 2.Service 层的单元测试
    • 2.1 创建一个实体类
    • 2.2 创建服务类
    • 2.3 编写测试
  • 3.Repository

1.Controller 层的单元测试

下面通过实例演示如何在控制器中使用 MockMvc 进行单元测试。

1.1 创建一个用于测试的控制器

package com.example.demo.controller;  import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;  @RestController public class HelloController {     @RequestMapping("/hello")     public String hello(String name) {         return "hello " + name;     } } 
  • @RestController:代表这个类是 REST 风格的控制器,返回 JSON/XML 类型的数据。
  • @RequestMapping:用于配置 URL 和方法之间的映射,可用在类和方法上。用于方法上,则其路径会继承用在类的路径上。

1.2 编写测试

package com.example.demo.controller;  import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext;  import static org.junit.Assert.*;  @SpringBootTest @RunWith(SpringRunner.class) public class HelloControllerTest {     //启用web上下文     @Autowired     private WebApplicationContext webApplicationContext;     private MockMvc mockMvc;      @Before     public void setUp() throws Exception{         //使用上下文构建mockMvc         mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();     }     @Test     public void hello() throws Exception {         // 得到MvcResult自定义验证         // 执行请求         MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/hello")                 .contentType(MediaType.APPLICATION_JSON_UTF8)                 //传入参数                 .param("name","longzhonghua")                 //接收的类型                 .accept(MediaType.APPLICATION_JSON_UTF8))                 //等同于Assert.assertEquals(200,status);                 //判断接收到的状态是否是200                 .andExpect(MockMvcResultMatchers.status().isOk())                  //等同于 Assert.assertEquals("hello longzhonghua",content);                 .andExpect(MockMvcResultMatchers.content().string("hello longzhonghua"))                 .andDo(MockMvcResultHandlers.print())         //返回MvcResult         .andReturn();         //得到返回代码         int status = mvcResult.getResponse().getStatus();         //得到返回结果         String content = mvcResult.getResponse().getContentAsString();         //断言,判断返回代码是否正确         Assert.assertEquals(200,status);         //断言,判断返回的值是否正确         Assert.assertEquals("hello longzhonghua",content);     } } 
  • @SpringBootTest:是 Spring Boot 用于测试的注解,可指定入口类或测试环境等。
  • @RunWith(SpringRunner.class):让测试运行于 Spring 的测试环境。
  • @Test:表示一个测试单元。
  • WebApplicationContext:启用 Web 上下文,用于获取 Bean 中的内容。
  • @Before:表示在测试单元执行前执行。这里使用上下文构建 MockMvc。
  • MockMvcRequestBuilders.get:指定请求方式是 GET。一般用浏览器打开网页就是 GET 方式。

运行测试,在控制器中会输出以下结果:

MockHttpServletRequest:       HTTP Method = GET       Request URI = /hello        Parameters = {name=[longzhonghua]}           Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json;charset=UTF-8"]              Body = null     Session Attrs = {}  Handler:              Type = com.example.demo.controller.HelloController            Method = public java.lang.String com.example.demo.controller.HelloController.hello(java.lang.String)  Async:     Async started = false      Async result = null  Resolved Exception:              Type = null  ModelAndView:         View name = null              View = null             Model = null  FlashMap:        Attributes = null  MockHttpServletResponse:            Status = 200     Error message = null           Headers = [Content-Type:"application/json;charset=UTF-8", Content-Length:"18"]      Content type = application/json;charset=UTF-8              Body = hello longzhonghua     Forwarded URL = null    Redirected URL = null           Cookies = [] 

在上述结果中可以看到 访问方式路径参数访问头ModelAndViewFlashMapMockHttpServletResponse

2.Service 层的单元测试

本实例演示如何在 Service 中使用 Assert 进行单元测试。

2.1 创建一个实体类

package com.example.demo.entity;  import lombok.Data; import lombok.Getter; import lombok.Setter;  @Data public class User {     private String name;     private int age; } 

2.2 创建服务类

这里用 @Service 来标注服务类,并实例化一个 User 对象。

package com.example.demo.service;  import com.example.demo.entity.User; import org.springframework.stereotype.Service;  @Service public class UserService {      public User getUserInfo(){         User user = new User();         user.setName("pipi");         user.setAge(18);         return user;     } } 

2.3 编写测试

编写测试用于比较实例化的实体 User 和测试预期值是否一样。

package com.example.demo.service;  import com.example.demo.entity.User; import org.junit.Assert;  import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.web.WebAppConfiguration;  import static org.hamcrest.CoreMatchers.*;  //表明要在测试环境运行,底层使用的junit测试工具 @RunWith(SpringRunner.class) // SpringJUnit支持,由此引入Spring-Test框架支持!  //启动整个spring的工程 @SpringBootTest public class UserServiceTest {     @Autowired     private UserService userService;      @Test     public void getUserInfo() {         User user = userService.getUserInfo();         //比较实际的值和用户预期的值是否一样         Assert.assertEquals(18, user.getAge());         Assert.assertThat(user.getName(), is("pipixia"));      } } 

运行测试,结果显示出错,表示期望的值和实际的值不一样。

在这里插入图片描述

3.Repository

Repository 层主要用于对数据进行增加、删除、修改和查询操作、它相当于仓库管理员的进出货操作。

下面通过实例演示如何在 Repository 中进行单元测试,以及使用 @Transactional 注解进行回滚操作。

package com.example.demo.repository;  import com.example.demo.entity.Card; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping;  import java.util.List;  import static org.junit.Assert.*;  @RunWith(SpringRunner.class) @SpringBootTest @Transactional public class CardRepositoryTest {     @Autowired     private CardRepository cardRepository;      @Test     public void testQuery() {         // 查询操作         List list = cardRepository.findAll();         for (Card card : list) {             System.out.println(card);         }     }      @Test     public void testRollBack() {         // 查询操作         Card card = new Card();         card.setNum(3);         cardRepository.save(card);         //throw new RuntimeException();     } } 
  • @Transactional:即回滚的意思。所有方法执行完之后哦,回滚成原来的样子。
  • testRollBack 方法:执行添加一条记录。如果开启了 @Transactional,则会在添加之后进行回滚,删除刚添加的数据,如果注释掉 @Transactional,则完成添加后不回滚。大家在测试时可以尝试去掉或添加 @Transactional 状态下的不同效果。这里的 @Transactional 放在类上,也可以加在方法上作用于方法。

运行 testQuery 测试,控制台输出如下:

在这里插入图片描述
在这里插入图片描述

运行 testRollBack 测试,并添加 @Transactional,控制台输出如下:

在这里插入图片描述

上述结果表示先添加,然后操作被立即回滚了。

在这里插入图片描述

运行 testRollBack 测试,去掉 @Transactional,控制台输出如下:

在这里插入图片描述
在这里插入图片描述

注:设置了 id 为自增键。

相关内容

热门资讯

第一些了解!奇迹陕西辅助器,w... 第一些了解!奇迹陕西辅助器,wejoker辅助机器人,德州教程(今日头条)1、每一步都需要思考,不同...
第9分钟科普!wpk辅助购买,... 第9分钟科普!wpk辅助购买,xpoker怎么透视挂,切实教程(证实有挂)-哔哩哔哩1、第9分钟科普...
5分钟了解“多乐辅助工具”详细... 5分钟了解“多乐辅助工具”详细透视开挂辅助软件-哔哩哔哩;多乐辅助工具是一种具有地方特色的麻将游戏,...
九分钟了解(Wepoke苹果版... 九分钟了解(Wepoke苹果版本)外挂透明挂辅助器(透视)系统教程(2021已更新)(哔哩哔哩);超...
第7秒钟了解!雀神广东麻将推倒... 第7秒钟了解!雀神广东麻将推倒胡辅助器下载,wepoker模拟器哪个好用,第三方教程(新版有挂)1、...
1分钟黑科技!hhpoker有... 1分钟黑科技!hhpoker有后台操控吗,wepoker私局代打,详细教程(有挂方式)-哔哩哔哩1、...
第2分钟了解“微乐家乡官方ap... 第2分钟了解“微乐家乡官方app下载”详细透视开挂辅助插件-哔哩哔哩;1、完成微乐家乡官方app下载...
5分钟了解(中至新余)外挂辅助... 您好,中至新余这款游戏可以开挂的,确实是有挂的,需要了解加微【136704302】很多玩家在这款游戏...
2刹那了解!wepoker辅助... 2刹那了解!wepoker辅助脚本,wepoker轻量版透视系统,德州教程(讲解有挂)1、该软件可以...
第三分钟晓得!wepoker透... 第三分钟晓得!wepoker透视破解版,wepoker模拟器哪个好用,必胜教程(有挂方针)-哔哩哔哩...