
在本系列的第一篇文章中,我们逐步介绍了如何使用 spring boot、cloudinary、docker 和 postgresql 构建一个强大的图像上传器。我们涵盖了从设置项目到向保存图像和信息的端点发出请求的所有内容。如果您还没有阅读那篇文章,我强烈建议您从那里开始,为我们将要使用的应用程序打下坚实的基础。
现在,是时候确保我们的应用程序可靠并随着时间的推移保持其完整性。这给我们带来了软件开发的一个关键方面:测试。在本文中,我们将重点为我们的图像上传器 api 编写单元测试。我们将探索如何模拟依赖关系,并编写涵盖服务不同部分的测试。
单元测试不仅有助于及早发现错误,还能确保我们的代码可维护和可扩展。在本文结束时,您将拥有一套针对图像上传器 api 的全面测试,让您确信您的应用程序按预期工作。
让我们深入单元测试的世界,让我们的图像上传器 api 防弹!
我正在使用 vscode 和 java 扩展包。现在我们准备好编写测试了。
如果您使用其他 ide,请参阅 junit5 文档中对所有这些 ide 的支持。
右键单击 bookservice 类,单击“go to test”,然后从菜单中选择要为其生成测试的方法。
将会生成一个类似的文件,如下所示:
import org.junit.jupiter.api.test;
public class bookservicetest {
@test
void testaddbook() {
}
}
请记住,对于本文,我们将使用 aaa 模式 进行测试(排列 - 执行 - 断言)。
@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<book> bookargumentcaptor;
@injectmocks
private bookservice bookservice;
}
@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<book> bookargumentcaptor;
@injectmocks
private bookservice bookservice;
@nested
class addbook {
@test
void shouldcreateanewbook() throws exception {
// arrange
map<string, object> 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<string, object> 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());
}
}
}
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 进行单元测试的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号