如何Mock带参构造的ServiceBusClient?NSubstitute使用求助
解决方法
核心问题是硬编码实例化ServiceBusClient导致无法模拟构造异常,解决思路是把客户端的创建逻辑抽离,解除代码与具体类的耦合,让创建过程可被Mock。
方案1:引入工厂接口(最直接的测试友好方案)
- 定义创建
ServiceBusClient的工厂接口:
public interface IServiceBusClientFactory { ServiceBusClient Create(string connectionString); }
- 实现默认工厂类:
public class DefaultServiceBusClientFactory : IServiceBusClientFactory { public ServiceBusClient Create(string connectionString) { return new ServiceBusClient(connectionString); } }
- 修改原有类,通过构造函数注入工厂,替换直接
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; } } }
- 用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
相关产品推荐
相关产品推荐

