java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot MockMVC单元测试

SpringBoot中MockMVC单元测试的实现

作者:一唸辶间

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单元测试内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文