You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单元测试中如何mock服务并编写FileServiceImpl的测试用例

FileServiceImpl单元测试Mock实现方案

核心测试逻辑

你需要实现的两个测试用例核心验证目标如下:

  • 异常场景:上传非.xlsx后缀的文件时,方法抛出指定IOException,且不会执行后续的上传记录保存、异步任务提交逻辑
  • 正常执行场景:上传.xlsx后缀的文件时,方法返回符合规则的Upload对象,且上传记录保存、异步任务提交逻辑都被正确调用

完整测试用例代码

在你已有测试类基础上补充两个测试方法即可:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
public class FileServiceImplTest {

    @Mock
    private ExecutorService executorService;

    @Mock
    private UploadsService uploadsService;

    @Mock
    private CandidatesService candidatesService;

    private FileServiceImpl fileService;

    private Upload upload;
    private MockMultipartFile file1, file2;

    @BeforeEach
    public void setUp() {
        fileService = new FileServiceImpl(executorService, uploadsService, candidatesService);
        // 正常xlsx后缀测试文件
        file1 = new MockMultipartFile("file", "filename.xlsx", "multipart/form-data", "test content".getBytes());
        // 非xlsx后缀测试文件,用于触发异常
        file2 = new MockMultipartFile("file", "filename.txt", "multipart/form-data", "test content".getBytes());
    }

    // 测试异常场景:非xlsx文件抛出IOException
    @Test
    public void uploadFile_WhenFileFormatWrong_ThrowsIOException() {
        // 验证抛出指定异常
        IOException exception = assertThrows(IOException.class, () -> fileService.uploadFile(file2));
        assertEquals("File format is not .xlsx", exception.getMessage());

        // 验证后续逻辑没有被执行
        verify(uploadsService, never()).saveUpload(any(Upload.class));
        verify(executorService, never()).execute(any(Runnable.class));
    }

    // 测试正常执行场景
    @Test
    public void uploadFile_WhenFileFormatCorrect_ReturnsUploadAndExecutesLogic() throws IOException {
        Upload result = fileService.uploadFile(file1);

        // 验证返回结果符合预期
        assertNotNull(result);
        assertEquals(UploadStatus.IN_PROGRESS, result.getStatus());
        assertEquals("filename.xlsx", result.getFilename());
        assertNotNull(result.getCreateTime());

        // 验证上传记录被保存
        verify(uploadsService, times(1)).saveUpload(any(Upload.class));
        // 验证异步任务被提交到线程池
        verify(executorService, times(1)).execute(any(XLSXAsyncImporter.class));

        // 可选:如果要严格校验saveUpload传入的参数属性,可以用ArgumentCaptor捕获参数校验
        // ArgumentCaptor<Upload> uploadCaptor = ArgumentCaptor.forClass(Upload.class);
        // verify(uploadsService).saveUpload(uploadCaptor.capture());
        // Upload savedUpload = uploadCaptor.getValue();
        // assertEquals(UploadStatus.IN_PROGRESS, savedUpload.getStatus());
        // assertEquals("filename.xlsx", savedUpload.getFilename());
    }
}

注意事项

  • 异步任务XLSXAsyncImporter的内部逻辑不属于FileServiceImpl的单元测试范围,不需要在这个测试类中验证,单独写XLSXAsyncImporter的测试用例即可
  • 这里用never()验证异常场景下后续方法不被调用,是为了避免非法请求产生脏数据或者多余资源占用的逻辑漏洞

内容的提问来源于stack exchange,提问作者pr_unikitty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 18:45:01