【单元测试】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 为自增键。

相关内容

热门资讯

aapoker俱乐部(智星德州... aapoker俱乐部(智星德州扑克)wepoke德扑之星(透视辅助)总是真的有挂(有挂下载)-小红书...
一分钟掌握!微扑克有辅助插件(... 一分钟掌握!微扑克有辅助插件(黑科技)外挂透明挂辅助神器(2020已更新)(百度知乎)微扑克有辅助插...
透视辅助挂!德扑ai助手&qu... 透视辅助挂!德扑ai助手"wpk有"的确是有挂的(有挂代打)-知乎德扑ai助手软件透明挂微扑克wpk...
透明辅助(菠萝德州)外挂软件透... 透明辅助(菠萝德州)外挂软件透明插件(辅助挂)一贯真的有挂(2023已更新)(哔哩哔哩);1.菠萝德...
aapoker俱乐部(微扑克)... aapoker俱乐部(微扑克)德扑ai助手软件(黑科技)其实真的有挂(有挂打法)-百度1、任何微扑克...
黑科技辅助挂!德扑之星猫腻&q... 黑科技辅助挂!德扑之星猫腻"来玩德州app外挂"本来真的有挂(有挂私人房)-头条来玩德州app外挂辅...
3分钟普及!微扑克这软件有问题... 3分钟普及!微扑克这软件有问题(辅助挂)外挂透明挂辅助脚本(2024已更新)(知乎)1、完成微扑克这...
德州辅助(aApoker)外挂... 德州辅助(aApoker)外挂软件透明软件(智能ai代打)本来真的有挂(2021已更新)(知乎);1...
德扑之星有猫腻(德州竞技联盟)... 德扑之星有猫腻(德州竞技联盟)德州ai人工智能(透视)其实真的有挂(有挂俱乐部)-微博热搜1、让任何...
透视辅助!aapoker辅助工... 透视辅助!aapoker辅助工具"wpk辅助软件查得出来"果真真的有挂(有挂黑科技)-今日头条wpk...