Skip to content

Commit 4ef5169

Browse files
committed
test: 增加 DefaultSocketClient 单元测试
1 parent 015528e commit 4ef5169

File tree

3 files changed

+62
-28
lines changed

3 files changed

+62
-28
lines changed

src/BootstrapBlazor/Services/TcpSocket/SocketClientBase.cs renamed to src/BootstrapBlazor/Services/TcpSocket/DefaultSocketClient.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace BootstrapBlazor.Components;
1313
/// TcpSocket 客户端默认实现
1414
/// </summary>
1515
[UnsupportedOSPlatform("browser")]
16-
public class SocketClientBase(IPEndPoint localEndPoint) : ISocketClient
16+
class DefaultSocketClient(IPEndPoint localEndPoint) : ISocketClient
1717
{
1818
private TcpClient? _client;
1919

@@ -25,15 +25,22 @@ public class SocketClientBase(IPEndPoint localEndPoint) : ISocketClient
2525
/// <summary>
2626
/// <inheritdoc/>
2727
/// </summary>
28-
public IPEndPoint LocalEndPoint { get; set; } = new IPEndPoint(IPAddress.Loopback, 0);
28+
public IPEndPoint LocalEndPoint { get; set; } = localEndPoint;
2929

3030
/// <summary>
3131
/// <inheritdoc/>
3232
/// </summary>
3333
public async ValueTask<bool> ConnectAsync(IPEndPoint endPoint, CancellationToken token = default)
3434
{
35-
_client = new TcpClient(localEndPoint);
35+
_client = new TcpClient(LocalEndPoint);
3636
await _client.ConnectAsync(endPoint, token);
37+
if (_client.Connected)
38+
{
39+
if (_client.Client.LocalEndPoint is IPEndPoint localEndPoint)
40+
{
41+
LocalEndPoint = localEndPoint;
42+
}
43+
}
3744
return _client.Connected;
3845
}
3946

src/BootstrapBlazor/Services/TcpSocket/DefaultTcpSocketClient.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
namespace BootstrapBlazor.Components;
1010

1111
[UnsupportedOSPlatform("browser")]
12-
sealed class DefaultTcpSocketClient : TcpSocketClientBase<SocketClientBase>
12+
sealed class DefaultTcpSocketClient : TcpSocketClientBase<DefaultSocketClient>
1313
{
1414
public DefaultTcpSocketClient(SocketClientOptions options)
1515
{
@@ -27,8 +27,8 @@ public DefaultTcpSocketClient(SocketClientOptions options)
2727
/// <param name="localEndPoint"></param>
2828
/// <returns></returns>
2929
/// <exception cref="NotImplementedException"></exception>
30-
protected override SocketClientBase CreateSocketClient(IPEndPoint localEndPoint)
30+
protected override DefaultSocketClient CreateSocketClient(IPEndPoint localEndPoint)
3131
{
32-
return new SocketClientBase(localEndPoint);
32+
return new DefaultSocketClient(localEndPoint);
3333
}
3434
}

test/UnitTest/Services/TcpSocketFactoryTest.cs

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using Microsoft.Extensions.Logging;
77
using System.Net;
88
using System.Net.Sockets;
9+
using System.Reflection;
10+
using System.Security.AccessControl;
911
using System.Text;
1012

1113
namespace UnitTest.Services;
@@ -193,7 +195,7 @@ public async Task ReceiveAsync_Cancel()
193195
var baseType = client.GetType().BaseType;
194196
Assert.NotNull(baseType);
195197

196-
var fieldInfo = baseType.GetField("_receiveCancellationTokenSource", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
198+
var fieldInfo = baseType.GetField("_receiveCancellationTokenSource", BindingFlags.NonPublic | BindingFlags.Instance);
197199
Assert.NotNull(fieldInfo);
198200
var tokenSource = fieldInfo.GetValue(client) as CancellationTokenSource;
199201
Assert.NotNull(tokenSource);
@@ -249,7 +251,7 @@ public async Task ReceiveAsync_Error()
249251
var baseType = client.GetType().BaseType;
250252
Assert.NotNull(baseType);
251253

252-
var methodInfo = baseType.GetMethod("AutoReceiveAsync", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
254+
var methodInfo = baseType.GetMethod("AutoReceiveAsync", BindingFlags.NonPublic | BindingFlags.Instance);
253255
Assert.NotNull(methodInfo);
254256

255257
var task = (ValueTask)methodInfo.Invoke(client, null)!;
@@ -462,9 +464,51 @@ public async Task DelimiterDataPackageHandler_Ok()
462464
public void Logger_Null()
463465
{
464466
// 测试 Logger 为 null 的情况
465-
var client = new MockTcpSocketClient();
466-
client.TestLog();
467-
Assert.Null(client.Logger);
467+
var client = CreateClient();
468+
var baseType = client.GetType().BaseType;
469+
Assert.NotNull(baseType);
470+
471+
// 获取 Logger 字段设置为 null 测试 Log 不会抛出异常
472+
var propertyInfo = baseType.GetProperty("Logger", BindingFlags.Public | BindingFlags.Instance);
473+
Assert.NotNull(propertyInfo);
474+
475+
propertyInfo.SetValue(client, null);
476+
477+
var methodInfo = baseType.GetMethod("Log", BindingFlags.NonPublic | BindingFlags.Instance);
478+
Assert.NotNull(methodInfo);
479+
methodInfo.Invoke(client, [LogLevel.Information, null!, "Test log message"]);
480+
}
481+
482+
[Fact]
483+
public async Task DefaultSocketClient_Ok()
484+
{
485+
var port = 8894;
486+
var server = StartTcpServer(port, MockDelimiterPackageAsync);
487+
var client = CreateClient();
488+
489+
// 获得 Client 泛型属性
490+
var baseType = client.GetType().BaseType;
491+
Assert.NotNull(baseType);
492+
493+
// 建立连接
494+
var connect = await client.ConnectAsync("localhost", port);
495+
Assert.True(connect);
496+
497+
var propertyInfo = baseType.GetProperty("Client", BindingFlags.NonPublic | BindingFlags.Instance);
498+
Assert.NotNull(propertyInfo);
499+
var instance = propertyInfo.GetValue(client);
500+
Assert.NotNull(instance);
501+
502+
ISocketClient socketClient = (ISocketClient)instance;
503+
Assert.NotNull(socketClient);
504+
Assert.True(socketClient.IsConnected);
505+
506+
await socketClient.CloseAsync();
507+
Assert.False(socketClient.IsConnected);
508+
509+
var buffer = new byte[10];
510+
var len = await socketClient.ReceiveAsync(buffer);
511+
Assert.Equal(0, len);
468512
}
469513

470514
private static TcpListener StartTcpServer(int port, Func<TcpClient, Task> handler)
@@ -677,21 +721,4 @@ public override async ValueTask ReceiveAsync(ReadOnlyMemory<byte> data, Cancella
677721
await base.ReceiveAsync(data, token);
678722
}
679723
}
680-
681-
class MockSoketClient(IPEndPoint localEndPoint) : SocketClientBase(localEndPoint)
682-
{
683-
}
684-
685-
class MockTcpSocketClient : TcpSocketClientBase<MockSoketClient>
686-
{
687-
protected override MockSoketClient CreateSocketClient(IPEndPoint localEndPoint)
688-
{
689-
return new MockSoketClient(localEndPoint);
690-
}
691-
692-
public void TestLog()
693-
{
694-
Log(LogLevel.Information, null, "test");
695-
}
696-
}
697724
}

0 commit comments

Comments
 (0)