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

如何Mock带参构造的ServiceBusClient?NSubstitute使用求助

解决方法

核心问题是硬编码实例化ServiceBusClient导致无法模拟构造异常,解决思路是把客户端的创建逻辑抽离,解除代码与具体类的耦合,让创建过程可被Mock。

方案1:引入工厂接口(最直接的测试友好方案)

  1. 定义创建ServiceBusClient的工厂接口:
public interface IServiceBusClientFactory
{
    ServiceBusClient Create(string connectionString);
}
  1. 实现默认工厂类:
public class DefaultServiceBusClientFactory : IServiceBusClientFactory
{
    public ServiceBusClient Create(string connectionString)
    {
        return new ServiceBusClient(connectionString);
    }
}
  1. 修改原有类,通过构造函数注入工厂,替换直接new的逻辑:
private readonly IServiceBusClientFactory _clientFactory;
private ServiceBusClient _client;
private readonly ILogger _logger;
private readonly string _connectionString;

public YourClassName(IServiceBusClientFactory clientFactory, ILogger logger, string connectionString)
{
    _clientFactory = clientFactory;
    _logger = logger;
    _connectionString = connectionString;
}

public void Connect()
{
    try
    {
        _client = _clientFactory.Create(_connectionString);
    }
    catch (Exception exception)
    {
        switch (exception)
        {
            case FormatException _:
                _logger.LogError(new ConnectionStringFormatError(_connectionString));
                break;
            case ServiceBusException _:
                _logger.LogError(new ConnectionError(exception.Message));
                break;
        }
    }
}
  1. 用NSubstitute模拟工厂抛出指定异常:
// 测试代码
var mockFactory = Substitute.For<IServiceBusClientFactory>();
// 模拟创建时抛出FormatException
mockFactory.Create(Arg.Any<string>()).Throws<FormatException>();
// 或者模拟抛出带自定义消息的ServiceBusException
mockFactory.Create(Arg.Any<string>()).Throws(new ServiceBusException("连接失败"));

// 初始化目标类,传入Mock工厂
var yourClass = new YourClassName(mockFactory, mockLogger, "test-connection-string");
yourClass.Connect();

// 验证日志是否正确触发
mockLogger.Received().LogError(Arg.Is<ConnectionStringFormatError>(e => e.ConnectionString == "test-connection-string"));

方案2:依赖注入直接注入ServiceBusClient(适合构造时初始化的场景)

如果Connect仅做初始化工作,也可以直接在类的构造函数中注入ServiceBusClient,依赖注入容器负责实例化。测试时,虽然ServiceBusClient是具体类,但Azure.Messaging.ServiceBus库中的它实现了IAsyncDisposable,不过要模拟构造异常,还是工厂模式更灵活直接。

关键逻辑

直接在方法内new具体类会形成紧耦合,无法替换为Mock实例。通过抽象工厂接口,把实例创建逻辑剥离出来,就能在测试中用NSubstitute替换工厂实现,模拟构造时的异常场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:30:14