SpringBoot中MockMVC单元测试的实现

 更新时间:2024年02月05日 10:44:44   作者:一唸辶间  
Mock是一种用于模拟和替换类的对象的方法,以便在单元测试中独立于外部资源进行测试,本文主要介绍了SpringBoot中MockMVC单元测试的实现,具有应该的参考价值,感兴趣的可以了解一下

在编写Springboot项目,如要对业务进行测试时,一般测试都是运行项目,通过URL在postman或者chrome浏览器进行测试,查看结果。

而当项目十分大的时候,我们在测试的时候,浪费的时间较多,因此我们通过使用SpringBoot MVC来进行单元测试。

可以实现对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。

如何使用MockMVC单元测试

Mock是一种用于模拟和替换类的对象的方法,以便在单元测试中独立于外部资源进行测试。使用Mock可以模拟各种对象,包括数据库连接、网络请求、外部服务调用等,以便在测试中检查代码的行为和输出。

以下是如何使用Mock来编写单元测试的步骤:

添加依赖

在项目的pom.xml文件中添加Mockito和JUnit的依赖。

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>3.12.4</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.8.1</version>
    <scope>test</scope>
</dependency>

创建测试类

在测试目录下创建一个新的测试类,例如MyServiceTest。

导入必要的类:在测试类中导入需要的类和注解。

import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

创建Mock对象

在测试类中使用@Mock注解创建需要Mock的对象。

@Mock
private MyRepository myRepository;

初始化Mock对象

在测试类的@BeforeEach或@Before方法中初始化Mock对象。

@BeforeEach
void setUp() {
    MockitoAnnotations.openMocks(this);
}

创建被测试的对象

在测试类中使用@InjectMocks注解创建被测试的对象,并将Mock对象注入到被测试对象中。

@InjectMocks
private MyService myService;

编写测试方法

在测试类中编写测试方法,并使用Mock对象来模拟需要的行为。

@Test
void testSomeMethod() {
    // 设置Mock对象的行为
    when(myRepository.findById(1L)).thenReturn(Optional.of(new MyEntity()));
    
    // 调用被测试的方法
    MyEntity result = myService.findById(1L);
    
    // 断言结果
    assertNotNull(result);
}

运行测试

在测试类中右键点击运行测试方法,或者使用Maven命令运行测试。

这样就可以使用Mockito和JUnit来编写单元测试了。Mockito提供了丰富的API来模拟对象的行为,使得单元测试更加简单和可控。

下面是某个模块的增加和更新操作测试相关代码如下(示例):

public class ClassificationControllerTest {
    @InjectMocks
    private ClassificationController classificationController;
    
    private MockMvc mockMvc;
    @Mock
    private ClassificationService classificationService;
    
    private ClassificationDto classificationDto;
    
    private Gson gson = new Gson();

    @Before
    public void before(){
        /*
        首先,MockitoAnnotations.initMocks(this) 是一个静态方法,用于初始化当前类的所有带有
        @Mock 注解的 mock 对象。这个方法会自动扫描当前类中的所有字段,如果发现带有 @Mock 注解的
        字段,就会自动初始化该字段对应的 mock 对象
         */
        MockitoAnnotations.initMocks(this);
        /*
        mockMvc = MockMvcBuilders.standaloneSetup(classificationController) 创建了一个
        MockMvc 实例,用于模拟 Spring MVC 的请求和响应。classificationController 是被测试的
        控制器对象。

        setControllerAdvice(new LocalExceptionAspect(), new GlobalExceptionHandler())
        方法设置了两个 advices,用于处理控制器中抛出的异常。LocalExceptionAspect 是本地异常处理,
        GlobalExceptionHandler 是全局异常处理。
         */
        mockMvc = MockMvcBuilders.standaloneSetup(classificationController)
                .setControllerAdvice(new LocalExceptionAspect(), new GlobalExceptionHandler())
                .build();
        classificationDto = new ClassificationDto();
        classificationDto.setName("Test-Test");
        classificationDto.setDescription("这是一个测试");
        classificationDto.setColour("#ccc119");
    }

    @Test
    public void add() throws Exception {
        /*
        MockMvc 是一个用于模拟 Spring MVC 请求和响应的类。通过 mockMvc.perform() 方法,
        可以创建一个 MockMvc 请求对象,并指定请求的 URL、请求方法、请求头、请求体等参数。
         */
        MvcResult result= mockMvc.perform(MockMvcRequestBuilders.post("/classification/add") //请求方法为post ,请求的url
                        .accept(MediaType.APPLICATION_JSON) // 指定请求头Accept   指定请求头Content-Type
                        .contentType(MediaType.APPLICATION_JSON).content(gson.toJson(classificationDto))) //方法指定请求体位xxx对象的json字符串表示
                .andReturn(); //返回一个MvcResult对象
        int statusCode = result.getResponse().getStatus();
        String content = result.getResponse().getContentAsString();
        System.out.println("statusCode: "+statusCode);
        System.out.println("返回结果 content: "+content);
        Assert.assertEquals(200, statusCode);  //验证响应状态码是否为200,表示请求成功
        /*
          验证classificationService是否被调用了一次,并且传入的参数类型是ClassificationDto类型。
          这个方法用于确认在测试用例执行过程中,是否正确调用了相关的服务方法。
         */
        verify(classificationService,times(1)).add(any(ClassificationDto.class));
    }

    @Test
    public void update() throws Exception {
        classificationDto.setId(119L);
        MvcResult result= mockMvc.perform(MockMvcRequestBuilders.put("/classification/update")
                        .accept(MediaType.APPLICATION_JSON)
                        .contentType(MediaType.APPLICATION_JSON).content(gson.toJson(classificationDto)))
                .andReturn();
        int statusCode = result.getResponse().getStatus();
        String content = result.getResponse().getContentAsString();
        System.out.println("statusCode: "+statusCode);
        System.out.println("返回结果 content: "+content);
        Assert.assertEquals(200, statusCode);
        verify(classificationService,times(1)).update(any(ClassificationDto.class));
    }
}

总结

在上面的示例代码中,我们首先使用了@Mock和@InjectMock注解来创建Mock对象并注入到测试类中。然后,我们可以定义了Mock对象的期望行为,当被调用时,返回一个包含测试数据的Optional对象。接下来,我们调用了被测试的方法,并获取了返回值。最后,我们使用断言语句来检查方法的行为和输出,包括验证被调用了一次,并验证返回值是否符合预期。

使用Mock可以有效地模拟外部依赖,使测试更加可控和可重复。这有助于提高测试的可靠性,并帮助开发人员更好地理解代码的行为和输出。

到此这篇关于SpringBoot中MockMVC单元测试的实现的文章就介绍到这了,更多相关SpringBoot MockMVC单元测试内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot+MyBatis-Plus实现分页功能

    SpringBoot+MyBatis-Plus实现分页功能

    在SpringBoot项目中,结合MyBatis-Plus(简称MP)可以非常方便地实现分页功能,MP为开发者提供了分页插件PaginationInterceptor,只需简单配置即可使用,本文给大家介绍了SpringBoot+MyBatis-Plus实现分页功能,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • springboot整合knife4j全过程

    springboot整合knife4j全过程

    这篇文章主要介绍了springboot整合knife4j全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Spring Boot 实现https ssl免密登录(X.509 pki登录)

    Spring Boot 实现https ssl免密登录(X.509 pki登录)

    这篇文章主要介绍了Spring Boot 实现https ssl免密登录(X.509 pki登录),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 动态代理模拟实现aop的示例

    动态代理模拟实现aop的示例

    下面小编就为大家带来一篇动态代理模拟实现aop的示例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望对大家有所帮助
    2017-11-11
  • Seata AT模式前后镜像是如何生成详解

    Seata AT模式前后镜像是如何生成详解

    这篇文章主要为大家介绍了Seata AT模式前后镜像是如何生成的方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • 排序算法图解之Java归并排序的实现

    排序算法图解之Java归并排序的实现

    归并排序是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。本文主要介绍了归并排序的实现,需要的可以参考一下
    2022-11-11
  • springboot操作ldap全过程

    springboot操作ldap全过程

    这篇文章主要介绍了springboot操作ldap全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • java睡眠排序算法示例实现

    java睡眠排序算法示例实现

    这篇文章主要为大家介绍了java睡眠排序算法的示例实现,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • 总结Java的Struts框架的异常处理方法

    总结Java的Struts框架的异常处理方法

    这篇文章主要介绍了Java的Struts框架的异常处理方法,Struts是Java的SSH三大web开发框架之一,需要的朋友可以参考下
    2015-12-12
  • Java常用类之System类的使用指南

    Java常用类之System类的使用指南

    System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。本文将通过示例为大家详细讲讲System类的使用,需要的可以参考一下
    2022-07-07

最新评论