Blazor 服务器页面单元测试 - 如何模拟 Blazor 服务器页面中使用的辅助 signalR 客户端连接
Blazor Server Page Unit Testing - How to mock secondary signalR client connection used in Blazor Server Page
我是 bUnit 的新用户,并且已经为 NavMenu
进行了一些测试 运行 以掌握基本概念。
但是,不同的 Blazor 页面向辅助 signalR 中心发出工作流状态通信请求。
如何模拟signalR连接?
https://github.com/dotnet/aspnetcore/issues/14924
使用额外的 signalR 连接来传达工作流状态的服务器页面
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var hubUrl = NavigationManager.BaseUri.TrimEnd('/') + "/motionhub";
try
{
Logger.LogInformation("Index.razor page is performing initial render, connecting to secondary signalR hub");
hubConnection = new HubConnectionBuilder()
.WithUrl(hubUrl)
.ConfigureLogging(logging =>
{
logging.AddConsole();
logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Information);
})
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions = JsonConvertersFactory.CreateDefaultJsonConverters(LoggerMotionDetection, LoggerMotionInfo, LoggerJsonVisitor);
})
.Build();
hubConnection.On<MotionDetection>("ReceiveMotionDetection", ReceiveMessage);
hubConnection.Closed += CloseHandler;
Logger.LogInformation("Starting HubConnection");
await hubConnection.StartAsync();
Logger.LogInformation("Index Razor Page initialised, listening on signalR hub => " + hubUrl.ToString());
}
catch (Exception e)
{
Logger.LogError(e, "Encountered exception => " + e);
}
}
}
存根单元测试Class
public class IndexTest : TestContext, IDisposable
{
private MotionDetectionRepository repo;
public IndexTest()
{
var mock = new Mock<IMotionDetectionSerializer<MotionDetection>>();
repo = new MotionDetectionRepository(mock.Object, new NullLogger<MotionDetectionRepository>());
Services.AddScoped<ILogger<MotionDetectionRepository>, NullLogger<MotionDetectionRepository>>();
Services.AddScoped<ILogger<MotionInfoConverter>, NullLogger<MotionInfoConverter>>();
Services.AddScoped<ILogger<MotionDetectionConverter>, NullLogger<MotionDetectionConverter>>();
Services.AddScoped<ILogger<JsonVisitor>, NullLogger<JsonVisitor>>();
Services.AddScoped<ILogger<WebApp.Pages.Index>, NullLogger<WebApp.Pages.Index>>();
Services.AddScoped<IMotionDetectionRepository>(sp => repo);
Services.AddScoped<MockNavigationManager>();
Services.AddSignalR();
}
[Fact]
public void Test()
{
var cut = RenderComponent<WebApp.Pages.Index>();
Console.WriteLine($"{cut.Markup}");
}
}
我使用这些经纪人。
public interface IHubConnectionsBroker
{
HubConnection CreateHubConnection(string endpoint, bool autoReconnect);
}
public interface IChatHubBroker
{
event EventHandler<ChatMessage> OnReceiveMessage;
event EventHandler<Exception> OnConnectionClosed;
event EventHandler<Exception> OnReconnecting;
event EventHandler<string> OnReconnected;
bool IsConnected { get; }
string ConnectionId { get; }
TimeSpan HandshakeTimeout { get; set; }
TimeSpan KeepAliveInterval { get; set; }
TimeSpan ServerTimeout { get; set; }
ChatHubBrokerState ChatHubBrokerState { get; }
ValueTask StartAsync();
ValueTask StopAsync();
ValueTask SendAsync(ChatMessage message);
ValueTask DisposeAsync();
}
我是 bUnit 的新用户,并且已经为 NavMenu
进行了一些测试 运行 以掌握基本概念。
但是,不同的 Blazor 页面向辅助 signalR 中心发出工作流状态通信请求。
如何模拟signalR连接? https://github.com/dotnet/aspnetcore/issues/14924
使用额外的 signalR 连接来传达工作流状态的服务器页面
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var hubUrl = NavigationManager.BaseUri.TrimEnd('/') + "/motionhub";
try
{
Logger.LogInformation("Index.razor page is performing initial render, connecting to secondary signalR hub");
hubConnection = new HubConnectionBuilder()
.WithUrl(hubUrl)
.ConfigureLogging(logging =>
{
logging.AddConsole();
logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Information);
})
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions = JsonConvertersFactory.CreateDefaultJsonConverters(LoggerMotionDetection, LoggerMotionInfo, LoggerJsonVisitor);
})
.Build();
hubConnection.On<MotionDetection>("ReceiveMotionDetection", ReceiveMessage);
hubConnection.Closed += CloseHandler;
Logger.LogInformation("Starting HubConnection");
await hubConnection.StartAsync();
Logger.LogInformation("Index Razor Page initialised, listening on signalR hub => " + hubUrl.ToString());
}
catch (Exception e)
{
Logger.LogError(e, "Encountered exception => " + e);
}
}
}
存根单元测试Class
public class IndexTest : TestContext, IDisposable
{
private MotionDetectionRepository repo;
public IndexTest()
{
var mock = new Mock<IMotionDetectionSerializer<MotionDetection>>();
repo = new MotionDetectionRepository(mock.Object, new NullLogger<MotionDetectionRepository>());
Services.AddScoped<ILogger<MotionDetectionRepository>, NullLogger<MotionDetectionRepository>>();
Services.AddScoped<ILogger<MotionInfoConverter>, NullLogger<MotionInfoConverter>>();
Services.AddScoped<ILogger<MotionDetectionConverter>, NullLogger<MotionDetectionConverter>>();
Services.AddScoped<ILogger<JsonVisitor>, NullLogger<JsonVisitor>>();
Services.AddScoped<ILogger<WebApp.Pages.Index>, NullLogger<WebApp.Pages.Index>>();
Services.AddScoped<IMotionDetectionRepository>(sp => repo);
Services.AddScoped<MockNavigationManager>();
Services.AddSignalR();
}
[Fact]
public void Test()
{
var cut = RenderComponent<WebApp.Pages.Index>();
Console.WriteLine($"{cut.Markup}");
}
}
我使用这些经纪人。
public interface IHubConnectionsBroker
{
HubConnection CreateHubConnection(string endpoint, bool autoReconnect);
}
public interface IChatHubBroker
{
event EventHandler<ChatMessage> OnReceiveMessage;
event EventHandler<Exception> OnConnectionClosed;
event EventHandler<Exception> OnReconnecting;
event EventHandler<string> OnReconnected;
bool IsConnected { get; }
string ConnectionId { get; }
TimeSpan HandshakeTimeout { get; set; }
TimeSpan KeepAliveInterval { get; set; }
TimeSpan ServerTimeout { get; set; }
ChatHubBrokerState ChatHubBrokerState { get; }
ValueTask StartAsync();
ValueTask StopAsync();
ValueTask SendAsync(ChatMessage message);
ValueTask DisposeAsync();
}