英文:
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<IServiceBusClientFactory>();
clientMock.GetServiceBusClient(Arg.Any<string>()).Returns(x => throw new FormatExcepction());
Of course, this requires usage of IoC - then you'll benefit from abstractions usage.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论