如何模拟ServiceBusClient

问题描述 投票:0回答:2

我有下一个方法,请注意我正在做

new ServiceBusClient(connectionString)
,我希望我可以模拟它,以便它抛出一个期望的异常。我正在使用 NSubstitute,但我不知道如何做到这一点。

 public void Connect()
        {
            try
            {
                client = new ServiceBusClient(connectionString);
            }
            catch (Exception exception)
            {
                switch (exception)
                {
                    case FormatException _:
                        logger.LogError(new ConnectionStringFormatError(connectionString));
                        break;
                    case ServiceBusException _:
                        logger.LogError(new ConnectionError(exception.Message));
                        break;
                }
            }
        }

ServiceBusClient 的构造函数有参数,所以我无法模拟类本身。有什么方法可以得到这个吗?

c# azure mocking
2个回答
4
投票

为了使此代码可测试并模拟

ServiceBusClient
,您不应直接在代码中使用它,而应通过抽象来使用它。

因此,首先创建工厂的抽象,它将为您创建服务总线客户端。像这样的东西:


public interface IServiceBusClientFactory
{
   ServiceBusClient GetServiceBusClient();
}

然后你需要实现这个抽象。这个抽象的实现将创建

ServiceBusClient

的实例

public class ServiceBusClientFactory : IServiceBusClientFactory
{
    private readonly string _connStr;


    public ServiceBusClientFactory(string connStr)
    {
        if(string.IsNullOrEmpty(connStr))
        {
            throw new ArgumentNullException(nameof(connStr));
        }

        _connStr = connStr;
    }

    public ServiceBusClient GetServiceBusClient()
    {
        return new ServiceBusClient(_connStr);
    }
}

然后你的客户端代码将使用

IServiceBusClientFactory
接口,你可以在单元测试中随意模拟它。

var clientMock = Substitute.For<IServiceBusClientFactory>();
clientMock.GetServiceBusClient(Arg.Any<string>()).Returns(x => throw new FormatExcepction());

当然,这需要使用 IoC - 那么您将受益于抽象的使用。


0
投票

ServiceBusClient 文档 建议在应用程序的生命周期内缓存和重用客户端。因此,您的

Connect
方法不应创建新的
ServiceBusClient
客户端。相反,它应该使用在 DI 容器中创建并注入到您的类中的现有实例。在那里,您可以调用
CreateSender
CreateReceiver
方法。

Azure SDK GitHub 页面有一些模拟客户端的示例。比如如何mock

CreateSender
方法:

Mock<ServiceBusClient> mockClient = new();
Mock<ServiceBusSender> mockSender = new();

// This sets up the mock ServiceBusClient to return the mock of the ServiceBusSender.

mockClient
    .Setup(client =>client.CreateSender(It.IsAny<string>()))
    .Returns(mockSender.Object);
© www.soinside.com 2019 - 2024. All rights reserved.