如何模拟 ServiceBusClient

huangapple go评论113阅读模式
英文:

How to mock ServiceBusClient

问题

我有以下方法,请注意我正在执行`new ServiceBusClient(connectionString)`,我希望我可以模拟它以抛出所需的异常。我正在使用NSubstitute,但我不知道该如何做。

```csharp
 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的构造函数有参数,所以我无法模拟该类本身。有没有办法解决这个问题?```

英文:

I have the next method, notice that I'm doing new ServiceBusClient(connectionString), I'd like i could mock this so it throws a desire exception. I'm using NSubstitute, but I have no idea how I could do this.

 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's constructor has parameters, so I can't mock the class itself. Is there any approch to get this?

答案1

得分: 2

为了使这段代码可测试,并模拟ServiceBusClient,您不应该直接在您的代码中使用它,而是通过抽象来使用它。

首先创建工厂的抽象,该工厂将为您创建Service Bus客户端,类似于这样:

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 FormatException());

当然,这需要使用IoC容器进行使用 - 这样您将从抽象的使用中获益。

英文:

In order to make this code testable, and mock ServiceBusClient, you should not use it directly in your code, but via abstraction.

So first create abstraction of the factory, which will create service bus client for you. Something like this:


public interface IServiceBusClientFactory
{
   ServiceBusClient GetServiceBusClient();
}

Then you need implementation of this abstraction. And implementation of this abstraction will create instance of 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);
    }
}

Then your client code will use IServiceBusClientFactory interface, and you could mock it in unit test as much as you like.

var clientMock = Substitute.For&lt;IServiceBusClientFactory&gt;();
clientMock.GetServiceBusClient(Arg.Any&lt;string&gt;()).Returns(x =&gt; throw new FormatExcepction());

Of course, this requires usage of IoC - then you'll benefit from abstractions usage.

huangapple
  • 本文由 发表于 2023年6月8日 17:25:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76430400.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定