201 lines
5.7 KiB
C#
201 lines
5.7 KiB
C#
using Sharp.NetServer;
|
|
using Sharp.NetServer.Server;
|
|
using Sharp.NetServer.Attributes;
|
|
using Sharp.NetServer.Controllers;
|
|
using Sharp.NetServer.Models;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
namespace NetServer.Test.IntegrationTests;
|
|
|
|
/// <summary>
|
|
/// 集成测试 - 测试完整的服务器功能
|
|
/// </summary>
|
|
[TestClass]
|
|
public class ServerIntegrationTests
|
|
{
|
|
private static HttpServer? _server;
|
|
private static readonly int TestPort = 15000;
|
|
private static readonly string BaseUrl = $"http://localhost:{TestPort}/";
|
|
|
|
[ClassInitialize]
|
|
public static async Task ClassInitialize(TestContext context)
|
|
{
|
|
// 启动测试服务器
|
|
var builder = new HttpServerBuilder();
|
|
builder.UseUrls(BaseUrl);
|
|
builder.AddControllers(typeof(ServerIntegrationTests).Assembly);
|
|
builder.UseCors();
|
|
builder.UseRateLimit();
|
|
|
|
builder.ConfigureLogging(services =>
|
|
{
|
|
services.AddLogging(logging =>
|
|
{
|
|
logging.SetMinimumLevel(LogLevel.Warning); // 减少测试输出
|
|
});
|
|
});
|
|
|
|
_server = builder.Build();
|
|
|
|
// 在后台启动服务器
|
|
_ = Task.Run(async () => await _server.StartAsync());
|
|
|
|
// 等待服务器启动
|
|
await Task.Delay(1000);
|
|
}
|
|
|
|
[ClassCleanup]
|
|
public static void ClassCleanup()
|
|
{
|
|
_server?.Stop();
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task Server_ShouldRespondToGetRequest()
|
|
{
|
|
// Arrange
|
|
using var client = new HttpClient();
|
|
client.BaseAddress = new Uri(BaseUrl);
|
|
|
|
// Act
|
|
var response = await client.GetAsync("api/integration/hello");
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
|
|
// Assert
|
|
Assert.IsTrue(response.IsSuccessStatusCode);
|
|
Assert.IsTrue(content.Contains("success"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task Server_ShouldHandleQueryParameters()
|
|
{
|
|
// Arrange
|
|
using var client = new HttpClient();
|
|
client.BaseAddress = new Uri(BaseUrl);
|
|
|
|
// Act
|
|
var response = await client.GetAsync("api/integration/echo?message=TestMessage");
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
|
|
// Assert
|
|
Assert.IsTrue(response.IsSuccessStatusCode);
|
|
Assert.IsTrue(content.Contains("TestMessage"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task Server_ShouldHandlePostRequest()
|
|
{
|
|
// Arrange
|
|
using var client = new HttpClient();
|
|
client.BaseAddress = new Uri(BaseUrl);
|
|
var jsonContent = new StringContent(
|
|
"{\"name\":\"Test User\",\"age\":25}",
|
|
System.Text.Encoding.UTF8,
|
|
"application/json"
|
|
);
|
|
|
|
// Act
|
|
var response = await client.PostAsync("api/integration/data", jsonContent);
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
|
|
// Assert
|
|
Assert.IsTrue(response.IsSuccessStatusCode);
|
|
Assert.IsTrue(content.Contains("Test User"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task Server_ShouldReturn404ForInvalidRoute()
|
|
{
|
|
// Arrange
|
|
using var client = new HttpClient();
|
|
client.BaseAddress = new Uri(BaseUrl);
|
|
|
|
// Act
|
|
var response = await client.GetAsync("api/invalid/route");
|
|
|
|
// Assert
|
|
Assert.AreEqual(System.Net.HttpStatusCode.NotFound, response.StatusCode);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task Server_ShouldHandleCors()
|
|
{
|
|
// Arrange
|
|
using var client = new HttpClient();
|
|
client.BaseAddress = new Uri(BaseUrl);
|
|
client.DefaultRequestHeaders.Add("Origin", "http://localhost:3000");
|
|
|
|
// Act
|
|
var response = await client.GetAsync("api/integration/hello");
|
|
|
|
// Assert
|
|
Assert.IsTrue(response.Headers.Contains("Access-Control-Allow-Origin"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task Server_ShouldHandleMultipleConcurrentRequests()
|
|
{
|
|
// Arrange
|
|
using var client = new HttpClient();
|
|
client.BaseAddress = new Uri(BaseUrl);
|
|
var tasks = new List<Task<HttpResponseMessage>>();
|
|
|
|
// Act - 发送 10 个并发请求
|
|
for (var i = 0; i < 10; i++) tasks.Add(client.GetAsync($"api/integration/concurrent?id={i}"));
|
|
|
|
var responses = await Task.WhenAll(tasks);
|
|
|
|
// Assert
|
|
Assert.AreEqual(10, responses.Length);
|
|
Assert.IsTrue(responses.All(r => r.IsSuccessStatusCode));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 集成测试控制器
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/integration")]
|
|
internal class IntegrationTestController : BaseController
|
|
{
|
|
[AllowAnonymous]
|
|
[HttpGet("hello")]
|
|
public async Task HelloAsync(HttpContext context)
|
|
{
|
|
await WriteSuccessResponseAsync(context, new
|
|
{
|
|
message = "Hello from integration test",
|
|
timestamp = DateTime.UtcNow
|
|
});
|
|
}
|
|
|
|
[AllowAnonymous]
|
|
[HttpGet("echo")]
|
|
public async Task EchoAsync(HttpContext context)
|
|
{
|
|
var message = GetQueryParam(context, "message", "");
|
|
await WriteSuccessResponseAsync(context, new { echo = message });
|
|
}
|
|
|
|
[AllowAnonymous]
|
|
[HttpPost("data")]
|
|
public async Task PostDataAsync(HttpContext context)
|
|
{
|
|
var data = await ReadJsonBodyAsync<Dictionary<string, object>>(context);
|
|
await WriteSuccessResponseAsync(context, new
|
|
{
|
|
received = data,
|
|
processedAt = DateTime.UtcNow
|
|
});
|
|
}
|
|
|
|
[AllowAnonymous]
|
|
[HttpGet("concurrent")]
|
|
public async Task ConcurrentAsync(HttpContext context)
|
|
{
|
|
var id = GetQueryParam(context, "id", "0");
|
|
await Task.Delay(50); // 模拟一些处理时间
|
|
await WriteSuccessResponseAsync(context, new { id, processed = true });
|
|
}
|
|
} |