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

使用Mockito测试Azure存储服务层报Invalid connection string错误如何解决

问题根因

你当前测试抛出异常的直接原因是@InjectMocks初始化AzureCloudStorageService时,依赖的PropertyResolver没有被Mock,导致读取到的connectionString为null,传入Azure客户端构造方法时触发非法连接串校验失败。
你原本设想的不做大量Mock直接调用方法验证是集成测试的逻辑,需要加载Spring上下文读取配置,而你当前编写的是单元测试,需要Mock所有外部依赖避免真实调用第三方服务。

解决方案

方案1:单元测试(无需连接真实Azure服务)

第一步:引入依赖(如果未引入)

要Mock构造方法需要引入mockito-inline依赖,Maven配置如下:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>和你项目中mockito-core版本一致</version>
    <scope>test</scope>
</dependency>

第二步:编写单元测试代码

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.core.env.PropertyResolver;
import org.springframework.web.multipart.MultipartFile;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

@ExtendWith(MockitoExtension.class)
public class AzureCloudStorageServiceTest {
    @Mock
    private PropertyResolver propertyResolver;
    @Mock
    private ModelMapper modelMapper;
    @Mock
    private BlobServiceClient blobServiceClient;
    @Mock
    private BlobContainerClient blobContainerClient;
    @Mock
    private BlobClient blobClient;

    @InjectMocks
    private AzureCloudStorageService azureCloudStorageService;

    @BeforeEach
    void setUp() {
        // Stub配置读取的返回值,替换null为合法的伪造配置
        when(propertyResolver.getProperty("azure.connection.string")).thenReturn("fake-connection-string");
        when(propertyResolver.getProperty("azure.container.name")).thenReturn("test-container");
    }

    @Test
    void upload_shouldReturnValidBlobUrlWhenSuccess() throws Exception {
        // 准备测试数据
        MultipartFile testFile = ModelUtils.getFile();
        String expectedBlobUrl = "https://test.blob.core.windows.net/test-container/test.jpg";
        String originalFileName = testFile.getOriginalFilename();

        // Mock BlobServiceClientBuilder构造及调用逻辑
        try (MockedConstruction<BlobServiceClientBuilder> mockedBuilder = mockConstruction(BlobServiceClientBuilder.class)) {
            // Stub构造器链式调用逻辑
            BlobServiceClientBuilder builderMock = mockedBuilder.constructed().get(0);
            when(builderMock.connectionString(anyString())).thenReturn(builderMock);
            when(builderMock.buildClient()).thenReturn(blobServiceClient);

            // Stub后续Azure客户端调用逻辑
            when(blobServiceClient.getBlobContainerClient("test-container")).thenReturn(blobContainerClient);
            when(blobContainerClient.getBlobClient(argThat(blobName -> blobName.endsWith(originalFileName)))).thenReturn(blobClient);
            doNothing().when(blobClient).upload(any(), eq(testFile.getSize()));
            when(blobClient.getBlobUrl()).thenReturn(expectedBlobUrl);

            // 执行测试方法
            String actualBlobUrl = azureCloudStorageService.upload(testFile);

            // 验证结果及调用链路
            assertEquals(expectedBlobUrl, actualBlobUrl);
            verify(blobClient, times(1)).upload(any(InputStream.class), eq(testFile.getSize()));
        }
    }
}

方案2:集成测试(真实调用Azure服务验证)

如果你需要验证真实的上传逻辑,就采用集成测试方案:

  1. 在test/resources/application.properties中添加真实的Azure测试账号配置:
azure.connection.string=你的Azure存储账号真实连接串
azure.container.name=你的测试容器名称
  1. 编写集成测试代码:
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.web.multipart.MultipartFile;
import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
public class AzureCloudStorageServiceIntegrationTest {
    @Autowired
    private AzureCloudStorageService azureCloudStorageService;

    @Test
    void upload_shouldReturnValidBlobUrlWhenSuccess() {
        MultipartFile testFile = ModelUtils.getFile();
        String blobUrl = azureCloudStorageService.upload(testFile);
        // 验证返回的url不为空、包含容器名等规则即可,不需要固定值匹配
        assertNotNull(blobUrl);
        assertTrue(blobUrl.contains("test-container"));
    }
}

注意事项

你原测试中写的expected = "image"不符合实际逻辑,服务返回的是完整的Azure Blob访问URL,不要做固定值匹配,要么Mock返回固定URL做单元测试断言,要么集成测试时做规则校验。

内容的提问来源于stack exchange,提问作者Євген Буфан

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:54:05