#.net #.net-core #mocking #signalr #xunit
#.net #.net-ядро #издевательство #signalr #xunit ( единица измерения ) #xunit
Вопрос:
Мне нужно протестировать ClientConnectionProvider
класс, но я не могу издеваться private IHubContext<SignalrServerHub, IBroadcast> HubContext { get; set; }
в тестовом классе, приведенном ниже. Как я могу издеваться над клиентом в hubcontext
, используемом в тестовом классе?
public class ClientConnectionProvider : IConnectionProvider
{
private readonly ILogger<ClientConnectionProvider> logger;
private IHubContext<SignalrServerHub, IBroadcast> HubContext { get; set;}
/// <summary>
/// Initializes a new instance of the <see cref="ClientConnectionProvider"/> class.
/// </summary>
/// <param name="logger"></param>
/// <param name="hubContext"></param>
public ClientConnectionProvider(ILogger<ClientConnectionProvider> logger, IHubContext<SignalrServerHub, IBroadcast> hubContext)
{
this.logger = logger;
HubContext = hubContext;
}
/// <summary>
/// To create and save a connection based on clients on connect.
/// </summary>
/// <param name="groupName"><see cref="string"/>.</param>
/// <returns>Task of <see cref="Task"/>.</returns>
public async Task<ServiceMethodResponse> SubscribeConnectionToAGroup(ClientConnection connection)
{
await HubContext.Groups.AddToGroupAsync(connection.ConnectionId, "HubUsers");
return new ServiceMethodResponse()
{
IsSuccess = true,
IsValid = true,
Message = "Subscribed to a group"
};
}
}
public class ConnectionProviderTest
{
private Mock<ILogger<ClientConnectionProvider>> logger;
private Mock<IDispatcher> dispatcher;
private Mock<IServiceProvider> serviceProvider;
private Mock<IConnectionProvider> connectionProvider;
private Mock<IHubContext<SignalrServerHub, IBroadcast>> HubContext;
//Mock<IClientProxy> mockClientProxy = new Mock<IClientProxy>();
private Mock<IClientProxy> mockClientProxy = new Mock<IClientProxy>();
/// <summary>
/// Initializes a new instance of the <see cref="ConnectionProviderTest"/> class.
/// </summary>
public ConnectionProviderTest()
{
this.logger = new Mock<ILogger<ClientConnectionProvider>>();
this.HubContext = new Mock<IHubContext<SignalrServerHub, IBroadcast>>();
this.connectionProvider = new Mock<IConnectionProvider>();
this.dispatcher = new Mock<IDispatcher>();
}
[Fact]
public async Task SendNotificationToAllFoundSuccess()
{
Mock<IHubClients> mockClients = new Mock<IHubClients>();
Mock<IClientProxy> mockClientProxy = new Mock<IClientProxy>();
mockClients.Setup(clients => clients.All).Returns(mockClientProxy.Object);
ClientConnectionProvider clientConnectionProvider = new ClientConnectionProvider( this.logger.Object, this.HubContext.Object);
this.HubContext.Setup(x => x.Clients).Returns(() => (IHubClients<IBroadcast>)mockClients.Object);
NotificationPayload payload = new NotificationPayload
{
Message = "RnadomHashString",
SubscriptionTypes = new List<SubscriptionType>() { new SubscriptionType { SubscriptionTypeName = "HubUsers" } },
};
ServiceMethodResponse response = await clientConnectionProvider.SendNotificationToAll(payload).ConfigureAwait(true);
Assert.True(response.IsValid);
}
}
Как мне протестировать методы ClientConnectionProvider? Получение ошибки системы.Исключение InvalidCastException : невозможно привести объект типа 'Castle.Proxies.IHubClients`1Proxy'
к типу 'Microsoft.AspNetCore.SignalR.IHubClients`1[Platform.PushNotification.Services.SignalRHub.IBroadcast]'
.
Ответ №1:
Возможно, я не совсем ясно выразился раньше. Что я хотел сказать:
- вы могли бы обернуть экземпляр SignalrServerHub, используемый в IHubContext, в свой реальный код.
- затем вы могли бы издеваться над этим интерфейсом.
Исключение, которое вы получаете, связано с тем, что класс SignalrServerHub нельзя издеваться, поскольку он не связан.
// The wrapper interface
public interface ISignalrServerHub
{
// Specify the methods / properties of SignalrServerHub, which you need
void SomeMethodYouNeed();
bool SomeMethodWithReturnValue();
}
// The wrapper
public class WrappedSignalrServerHub : ISignalrServerHub
{
private SingalrServerHub _wrappedInstance;
public WrappedSignalrServerHub(SignalrServerHub instance)
{
_wrappedInstance = instance; // TODO add null check
}
public void SomeMethodYouNeed()
{
_wrappedInstance.SomeMethodYouNeed();
}
public bool SomeMethodWithReturnValue()
{
return _wrappedInstance.SomeMethodWithReturnValue();
}
}
// The changed class
public class ClientConnectionProvider : IConnectionProvider
{
private readonly ILogger<ClientConnectionProvider> logger;
private IHubContext<ISignalrServerHub, IBroadcast> HubContext { get; set;}
/// <summary>
/// Initializes a new instance of the <see cref="ClientConnectionProvider"/> class.
/// </summary>
/// <param name="logger"></param>
/// <param name="hubContext"></param>
public ClientConnectionProvider(ILogger<ClientConnectionProvider> logger, IHubContext<ISignalrServerHub, IBroadcast> hubContext)
{
this.logger = logger;
HubContext = hubContext;
}
// [snipped for brevity]
}
// The changed test
public class ConnectionProviderTest
{
// [snipped for brevity]
private Mock<IHubContext<ISignalrServerHub, IBroadcast>> HubContext;
// [snipped for brevity]
/// <summary>
/// Initializes a new instance of the <see cref="ConnectionProviderTest"/> class.
/// </summary>
public ConnectionProviderTest()
{
this.logger = new Mock<ILogger<ClientConnectionProvider>>();
this.HubContext = new Mock<IHubContext<ISignalrServerHub, IBroadcast>>();
this.connectionProvider = new Mock<IConnectionProvider>();
this.dispatcher = new Mock<IDispatcher>();
}
// [snipped for brevity]
}
Комментарии:
1. Это не помогает.
2. Я обновил свой ответ. Возможно, это удовлетворит ваши потребности.