使用 JUnitnd Mockito 对图像上传器 API 进行单元测试

使用 junitnd mockito 对图像上传器 api 进行单元测试

在本系列的第一篇文章中,我们逐步介绍了如何使用 spring boot、cloudinary、docker 和 postgresql 构建一个强大的图像上传器。我们涵盖了从设置项目到向保存图像和信息的端点发出请求的所有内容。如果您还没有阅读那篇文章,我强烈建议您从那里开始,为我们将要使用的应用程序打下坚实的基础。

现在,是时候确保我们的应用程序可靠并随着时间的推移保持其完整性。这给我们带来了软件开发的一个关键方面:测试。在本文中,我们将重点为我们的图像上传器 api 编写单元测试。我们将探索如何模拟依赖关系,并编写涵盖服务不同部分的测试。

单元测试不仅有助于及早发现错误,还能确保我们的代码可维护和可扩展。在本文结束时,您将拥有一套针对图像上传器 api 的全面测试,让您确信您的应用程序按预期工作。

让我们深入单元测试的世界,让我们的图像上传器 api 防弹!

配置

我正在使用 vscode 和 java 扩展包。现在我们准备好编写测试了。

如果您使用其他 ide,请参阅 junit5 文档中对所有这些 ide 的支持。

测试

1. 图书服务测试

右键单击 bookservice 类,单击“go to test”,然后从菜单中选择要为其生成测试的方法。

将会生成一个类似的文件,如下所示:

import org.junit.jupiter.api.test;public class bookservicetest {    @test    void testaddbook() {    }}

登录后复制

请记住,对于本文,我们将使用 aaa 模式 进行测试(排列 – 执行 – 断言)。

1.1.模拟属性

@extendwith(mockitoextension.class)public class bookservicetest {    @mock    private bookrepository bookrepository;    @mock    private cloudinary cloudinary;    @mock    private multipartfile multipartfile;    @mock    private uploader uploader;    @captor    private argumentcaptor bookargumentcaptor;    @injectmocks    private bookservice bookservice;}

登录后复制@mock 注释模拟/模拟类将要使用的属性或依赖项的行为。@injectmocks 注解创建模拟并将其注入到相应的字段中。

1.2.编写测试

测试成功案例(shouldcreateanewbook)。测试对存储库的调用(shouldcallrepositorysave)。测试上传是否失败(shouldfailtheupload)。

@extendwith(mockitoextension.class)public class bookservicetest {    @mock    private bookrepository bookrepository;    @mock    private cloudinary cloudinary;    @mock    private multipartfile multipartfile;    @mock    private uploader uploader;    @captor    private argumentcaptor bookargumentcaptor;    @injectmocks    private bookservice bookservice;    @nested    class addbook {        @test        void shouldcreateanewbook() throws exception {            // arrange            map uploadresult = map.of("url", "http://example.com/image.jpg");            when(cloudinary.uploader()).thenreturn(uploader);            when(uploader.upload(any(file.class), anymap())).thenreturn(uploadresult);            book book = new book();            book.setname("test book");            book.setimgurl(uploadresult.get("url").tostring());            when(bookrepository.save(any(book.class))).thenreturn(book);            when(multipartfile.getoriginalfilename()).thenreturn("test.jpg");            when(multipartfile.getbytes()).thenreturn("test content".getbytes());            // act            book result = bookservice.addbook("test book", multipartfile);            // assert            assertnotnull(result);            assertequals("test book", result.getname());            assertequals("http://example.com/image.jpg", result.getimgurl());        }        @test        void shouldcallrepositorysave() throws exception {            // arrange            map uploadresult = map.of("url", "http://example.com/image.jpg");            when(cloudinary.uploader()).thenreturn(uploader);            when(uploader.upload(any(file.class), anymap())).thenreturn(uploadresult);            book book = new book();            book.setname("test book");            book.setimgurl(uploadresult.get("url").tostring());            when(bookrepository.save(any(book.class))).thenreturn(book);            when(multipartfile.getoriginalfilename()).thenreturn("test.jpg");            when(multipartfile.getbytes()).thenreturn("test content".getbytes());            // act            bookservice.addbook("test book", multipartfile);            // assert            verify(bookrepository, times(1)).save(bookargumentcaptor.capture());            book capturedbook = bookargumentcaptor.getvalue();            assertequals("test book", capturedbook.getname());            assertequals("http://example.com/image.jpg", capturedbook.getimgurl());        }        @test        void shouldfailtheupload() throws exception {            // arrange            when(multipartfile.getoriginalfilename()).thenreturn("test.jpg");            when(multipartfile.getbytes()).thenreturn("test content".getbytes());            when(cloudinary.uploader()).thenreturn(uploader);            when(uploader.upload(any(file.class),                    anymap())).thenthrow(ioexception.class);            // act & assert            responsestatusexception exception = assertthrows(responsestatusexception.class, () -> {                bookservice.addbook("test book", multipartfile);            });            assertequals(httpstatus.bad_gateway, exception.getstatuscode());            assertequals("failed to upload the file.", exception.getreason());        }    }}

登录后复制

2. 图书控制器测试

测试成功案例(shouldreturnsuccess)测试失败案例(shouldfailtouploadimage)使用缺少的名称参数进行测试(shouldfailwithmissingnameparameter)使用缺少的 imgurl 参数进行测试(shouldfailwithmissingimageparameter)

package cloudinary.upload.imageUpload.controllers;import static org.mockito.ArgumentMatchers.any;import static org.mockito.Mockito.when;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;import org.junit.jupiter.api.Nested;import org.junit.jupiter.api.Test;import org.junit.jupiter.api.extension.ExtendWith;import org.mockito.InjectMocks;import org.mockito.Mock;import org.mockito.junit.jupiter.MockitoExtension;import org.springframework.http.HttpStatus;import org.springframework.http.MediaType;import org.springframework.mock.web.MockMultipartFile;import org.springframework.test.web.servlet.MockMvc;import org.springframework.test.web.servlet.setup.MockMvcBuilders;import org.springframework.web.server.ResponseStatusException;import cloudinary.upload.imageUpload.configs.GlobalExceptionHandler;import cloudinary.upload.imageUpload.entities.Book;import cloudinary.upload.imageUpload.services.BookService;@ExtendWith(MockitoExtension.class)public class BookControllerTest {    @Mock    private BookService bookService;    @InjectMocks    private BookController bookController;    private MockMvc mockMvc;    @Nested    class AddBook {        @Test        void shouldReturnSuccess() throws Exception {            // Arrange            MockMultipartFile image = new MockMultipartFile("imgUrl", "test.jpg", MediaType.IMAGE_JPEG_VALUE,                    "test content".getBytes());            Book book = new Book();            book.setName("Test Book");            book.setImgUrl("http://example.com/image.jpg");            when(bookService.addBook(any(String.class), any(MockMultipartFile.class))).thenReturn(book);            mockMvc = MockMvcBuilders.standaloneSetup(bookController).build();            // Act & Assert            mockMvc.perform(multipart("/addBook")                    .file(image)                    .param("name", "Test Book"))                    .andExpect(status().isOk())                    .andExpect(jsonPath("$.name").value("Test Book"))                    .andExpect(jsonPath("$.imgUrl").value("http://example.com/image.jpg"));        }        @Test        void shouldFailToUploadImage() throws Exception {            // Arrange            MockMultipartFile image = new MockMultipartFile("imgUrl", "test.jpg", MediaType.IMAGE_JPEG_VALUE,                    "test content".getBytes());            when(bookService.addBook(any(String.class), any(MockMultipartFile.class)))                    .thenThrow(new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR,                            "Failed to upload the file."));            mockMvc = MockMvcBuilders.standaloneSetup(bookController).setControllerAdvice(new GlobalExceptionHandler())                    .build();            // Act & Assert            mockMvc.perform(multipart("/addBook")                    .file(image)                    .param("name", "Test Book"))                    .andExpect(status().isInternalServerError())                    .andExpect(result -> result.getResponse().equals("Failed to upload the file."));        }        @Test        void shouldFailWithMissingNameParameter() throws Exception {            // Arrange            MockMultipartFile image = new MockMultipartFile("imgUrl", "test.jpg", MediaType.IMAGE_JPEG_VALUE,                    "test content".getBytes());            mockMvc = MockMvcBuilders.standaloneSetup(bookController).build();            // Act & Assert            mockMvc.perform(multipart("/addBook")                    .file(image))                    .andExpect(status().isBadRequest());        }        @Test        void shouldFailWithMissingImageParameter() throws Exception {            // Arrange            mockMvc = MockMvcBuilders.standaloneSetup(bookController).build();            // Act & Assert            mockMvc.perform(multipart("/addBook")                    .param("name", "Test Book"))                    .andExpect(status().isBadRequest());        }    }}

登录后复制

结论

这些是一些简单的测试用例,供您开始测试您的应用程序。请记住,我们可以通过添加一些工厂来重构这些测试以避免重复。

感谢您的阅读。

参考

junit5 – 文档
mockito – 文档

以上就是使用 JUnitnd Mockito 对图像上传器 API 进行单元测试的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2610737.html

(0)
上一篇 2025年3月6日 21:08:13
下一篇 2025年2月24日 01:27:09

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Java框架对云原生应用的部署和运维有何影响?

    java 框架显著提升了云原生应用程序的部署和运维能力:部署优势:自动化部署管道容器化支持服务发现机制运维优势:容错特性日志记录和监控支持自动化扩缩容 Java 框架对云原生应用的部署和运维的影响 云原生应用通常部署在分布式、可扩展的基础设…

    2025年3月6日
    200
  • 指标可能会欺骗您:测量连接池环境中的执行时间

    测量外部服务请求的执行时间对于性能监控和优化至关重要。但是,当对这些外部服务的连接进行池化时,您可能会无意中测量的不仅仅是请求时间。具体来说,如果请求花费的时间太长并且您耗尽了可用连接,则您的自定义逻辑可能会开始包括从池中获取连接的等待时间…

    2025年3月6日
    200
  • Spring Security 与 JWT

    在本文中,我们将探讨如何将 spring security 与 jwt 集成,为您的应用程序构建坚实的安全层。我们将完成从基本配置到实现自定义身份验证过滤器的每个步骤,确保您拥有必要的工具来高效、大规模地保护您的 api。 配置 在 spr…

    2025年3月6日
    200
  • 如何使用 Docker 来隔离和测试 Java 函数

    答案:docker 允许隔离和测试 java 函数,通过创建轻量级容器实现。创建 dockerfile 构建容器镜像,指定 java 版本、依赖项和函数代码。构建镜像并运行容器,将函数运行在隔离环境中。采用单元测试、集成测试等技术,从容器内…

    2025年3月6日
    200
  • AWS Lambda 上的 Spring Boot 应用程序 – 使用 Docker 容器映像测量 Lambda 函数的冷启动和热启动部分

    介绍 在如何使用 Docker 容器镜像和 Java (21) 运行时开发和部署 Lambda 函数一文中,我逐步介绍了如何使用 Docker 容器镜像和 Java 21 运行时开发和部署 Lambda 函数,而不使用任何框架。由于 Doc…

    2025年3月6日
    200
  • 前端/后端主要配置文件

    从 DevOps 的角度来看,了解 Java 和 Node.js(后端和前端)代码库中的配置文件对于管理构建流程、部署和环境设置至关重要。以下是在 Java 和 Node.js 应用程序中需要注意的配置文件的完整列表: Java 应用程序 …

    2025年3月6日
    200
  • Spring Data JPA 中的高级查询技术

    我们已经探索了 spring data jpa 的基础知识以及方法命名约定如何使查询变得简单。如果没有,我强烈建议您先关注该博客。在第二部分中,我们将深入研究更高级的查询技术,使您能够利用强大的组合、排序、分页和特定于字符串的操作来更好地控…

    2025年3月6日
    200
  • 用Java编写kooperator

    本教程专门针对具有 java 背景、想要学习如何快速编写第一个 kubernetes 运算符的开发人员。为什么是运营商?有以下几个优点: 显着减少维护,节省击键次数弹性内置于您创建的任何系统中学习的乐趣,认真了解 kubernetes 的具…

    2025年3月6日
    200
  • Maven 入门

    阅读 maven 入门中的完整文章 概述 如果您是 java 开发人员,您可能使用过 maven 来构建和管理您的项目。 在这篇文章中,您将学习在项目中使用 maven 的基础知识。 了解 maven 的项目结构 my-maven-proj…

    2025年3月6日
    200
  • 塑造未来发展的关键发展中值得关注的 Java 趋势

    随着 Java 的不断发展,开发人员正在密切关注可能在 2024 年影响其项目的新兴趋势。重点可能会集中在增强的性能、增加的云集成以及现代框架的采用上,这些是对于保持科技领域的竞争力至关重要。 到 2024 年,通过引入新的垃圾收集技术和优…

    2025年3月6日
    200

发表回复

登录后才能评论