您的位置:首页 > 汽车 > 新车 > 【单元测试】Controller、Service、Repository 层的单元测试

【单元测试】Controller、Service、Repository 层的单元测试

2024/7/3 22:52:20 来源:https://blog.csdn.net/be_racle/article/details/140062004  浏览:    关键词:【单元测试】Controller、Service、Repository 层的单元测试

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上下文@Autowiredprivate WebApplicationContext webApplicationContext;private MockMvc mockMvc;@Beforepublic void setUp() throws Exception{//使用上下文构建mockMvcmockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();}@Testpublic 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 = GETRequest URI = /helloParameters = {name=[longzhonghua]}Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json;charset=UTF-8"]Body = nullSession Attrs = {}Handler:Type = com.example.demo.controller.HelloControllerMethod = public java.lang.String com.example.demo.controller.HelloController.hello(java.lang.String)Async:Async started = falseAsync result = nullResolved Exception:Type = nullModelAndView:View name = nullView = nullModel = nullFlashMap:Attributes = nullMockHttpServletResponse:Status = 200Error message = nullHeaders = [Content-Type:"application/json;charset=UTF-8", Content-Length:"18"]Content type = application/json;charset=UTF-8Body = hello longzhonghuaForwarded URL = nullRedirected URL = nullCookies = []

在上述结果中可以看到 访问方式路径参数访问头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 {@Autowiredprivate UserService userService;@Testpublic 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 {@Autowiredprivate CardRepository cardRepository;@Testpublic void testQuery() {// 查询操作List<Card> list = cardRepository.findAll();for (Card card : list) {System.out.println(card);}}@Testpublic 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 为自增键。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com