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

如何在命令行应用中使用Azurite进行Blob单元测试?

在命令行应用/单元测试中按需启动Azurite进行Blob验证

一、程序化启动Azurite(推荐方案)

不用手动命令行启动,直接通过代码控制Azurite的生命周期,从根源避免权限、端口冲突问题。

1. 准备工作

确保已安装Azurite:

  • 方式1:使用Visual Studio自带的Azurite,路径一般为C:\Program Files\Microsoft Visual Studio\2022\<版本>\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator\azurite.exe
  • 方式2:通过npm全局安装:npm install -g azurite,安装后可直接用azurite命令调用

2. 代码实现启动/停止Azurite

以下是命令行应用或单元测试中的核心代码:

using System.Diagnostics;
using System.Text;
using Azure.Storage.Blobs;

// 启动Azurite进程
var azuritePath = @"C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator\azurite.exe";
// 若用npm安装,替换为:
// var azuritePath = "node";
// var arguments = @"C:\Users\<你的用户名>\AppData\Roaming\npm\node_modules\azurite\dist\src\cli.js --blobHost 127.0.0.1 --blobPort 10002 --location C:\Temp\AzuriteData";

var arguments = "--blobHost 127.0.0.1 --blobPort 10002 --location C:\\Temp\\AzuriteData";
var processStartInfo = new ProcessStartInfo(azuritePath, arguments)
{
    CreateNoWindow = true,
    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardError = true
};

var azuriteProcess = Process.Start(processStartInfo);
// 等待Azurite初始化完成(可根据需要调整等待时间,或用端口监听逻辑替代)
await Task.Delay(2000);

// 自定义端口的连接字符串
var connectionString = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10002/devstoreaccount1;";
var blobServiceClient = new BlobServiceClient(connectionString);

// 执行Blob创建与验证逻辑
var containerClient = blobServiceClient.GetBlobContainerClient("test-container");
await containerClient.CreateIfNotExistsAsync();
var blobClient = containerClient.GetBlobClient("test-blob.txt");
await blobClient.UploadAsync(new MemoryStream(Encoding.UTF8.GetBytes("Test content")), overwrite: true);

// 验证Blob存在
var exists = await blobClient.ExistsAsync();
Debug.Assert(exists, "Blob未创建成功");

// 测试完成后关闭Azurite
azuriteProcess.Kill();
await azuriteProcess.WaitForExitAsync();
azuriteProcess.Dispose();

3. 解决权限与端口问题

  • EPERM权限错误:
    • 指定的--location路径需选当前用户有写入权限的文件夹(如C:\Temp\AzuriteData),避开系统盘根目录或受保护的文件夹
    • 不要用管理员权限启动命令行/应用,反而可能引发权限冲突
  • 端口被占用:
    • 在启动参数中指定非默认端口(如示例中的10002),避开10000等常用端口
    • 启动前可通过netstat -ano | findstr :10000查看占用进程,手动终止后再启动

二、集成到单元测试(以xUnit为例)

将Azurite的启动/关闭逻辑封装到Fixture中,实现测试类级别的生命周期管理:

using System.Diagnostics;
using System.Text;
using Azure.Storage.Blobs;
using Xunit;

public class AzuriteFixture : IAsyncLifetime
{
    private Process _azuriteProcess;
    public BlobServiceClient BlobServiceClient { get; private set; }

    public async Task InitializeAsync()
    {
        // 启动Azurite
        var azuritePath = @"C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator\azurite.exe";
        var arguments = "--blobHost 127.0.0.1 --blobPort 10002 --location C:\\Temp\\AzuriteData";
        var processStartInfo = new ProcessStartInfo(azuritePath, arguments)
        {
            CreateNoWindow = true,
            UseShellExecute = false
        };
        _azuriteProcess = Process.Start(processStartInfo);
        await Task.Delay(2000);

        // 初始化Blob客户端
        var connectionString = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10002/devstoreaccount1;";
        BlobServiceClient = new BlobServiceClient(connectionString);
    }

    public async Task DisposeAsync()
    {
        // 清理Azurite进程
        if (_azuriteProcess != null && !_azuriteProcess.HasExited)
        {
            _azuriteProcess.Kill();
            await _azuriteProcess.WaitForExitAsync();
            _azuriteProcess.Dispose();
        }
    }
}

// 使用Fixture的测试类
public class BlobUnitTests : IClassFixture<AzuriteFixture>
{
    private readonly AzuriteFixture _fixture;

    public BlobUnitTests(AzuriteFixture fixture)
    {
        _fixture = fixture;
    }

    [Fact]
    public async Task CreateAndVerifyBlob_Succeeds()
    {
        var containerClient = _fixture.BlobServiceClient.GetBlobContainerClient("test-container");
        await containerClient.CreateIfNotExistsAsync();
        
        var blobClient = containerClient.GetBlobClient("test-blob.txt");
        await blobClient.UploadAsync(new MemoryStream(Encoding.UTF8.GetBytes("Test content")), overwrite: true);
        
        var exists = await blobClient.ExistsAsync();
        Assert.True(exists);
    }
}

三、替代方案:用Docker启动Azurite

若本地有Docker环境,可直接启动Azurite容器,无需本地安装Azurite:

using System.Diagnostics;
using Azure.Storage.Blobs;

// 启动Azurite容器
var dockerStartInfo = new ProcessStartInfo("docker", "run -d -p 10002:10000 mcr.microsoft.com/azure-storage/azurite azurite-blob --blobHost 0.0.0.0")
{
    CreateNoWindow = true,
    UseShellExecute = false,
    RedirectStandardOutput = true
};
var dockerProcess = Process.Start(dockerStartInfo);
var containerId = await dockerProcess.StandardOutput.ReadLineAsync();
await Task.Delay(2000);

// 使用映射后的端口连接
var connectionString = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10002/devstoreaccount1;";
var blobServiceClient = new BlobServiceClient(connectionString);

// 执行Blob操作...

// 停止并删除容器
Process.Start("docker", $"stop {containerId}").WaitForExit();
Process.Start("docker", $"rm {containerId}").WaitForExit();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 20:50:56