Mico.Demo/Microservice.Common.Tests/ServiceClientTests.cs

256 lines
9.5 KiB
C#

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Logging;
using Moq;
using Nacos.V2;
using Nacos.V2.Common;
using Nacos.V2.Naming.Dtos;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using Xunit;
namespace Microservice.Common.Tests
{
public class ServiceClientTests
{
private readonly Mock<INacosNamingService> _nacosNamingServiceMock;
private readonly HttpClient _httpClient;
private readonly Mock<ILogger<ServiceClient>> _loggerMock;
private readonly ServiceClient _serviceClient;
public ServiceClientTests()
{
// 初始化模拟对象
_nacosNamingServiceMock = new Mock<INacosNamingService>();
_loggerMock = new Mock<ILogger<ServiceClient>>();
// 创建一个测试用的 HttpClient
var httpClientHandler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
};
_httpClient = new HttpClient(httpClientHandler);
// 创建 ServiceClient 实例
_serviceClient = new ServiceClient(_nacosNamingServiceMock.Object, _loggerMock.Object);
}
[Fact]
public async Task GetAsync_ShouldReturnSuccess_WhenServiceIsAvailable()
{
// Arrange
var serviceName = "TestService";
var endpoint = "/api/test";
var expectedResponse = new { Message = "Test Response" };
// 模拟 Nacos 服务发现返回一个健康的实例
var instance = new Instance
{
Ip = "127.0.0.1",
Port = 8080,
Healthy = true,
Enabled = true
};
_nacosNamingServiceMock.Setup(x => x.SelectOneHealthyInstance(serviceName)).ReturnsAsync(instance);
// 创建一个测试服务器
var testServer = new TestServer(new WebApplicationFactory<object>().WithWebHostBuilder(builder =>
{
builder.ConfigureServices(services =>
{
// 配置测试服务
});
builder.Configure(app =>
{
app.MapGet("/api/test", () => Results.Ok(expectedResponse));
});
}));
// 使用测试服务器的 HttpClient
var testHttpClient = testServer.CreateClient();
var testServiceClient = new ServiceClient(_nacosNamingServiceMock.Object, testHttpClient, _loggerMock.Object);
// Act
var result = await testServiceClient.GetAsync<object>(serviceName, endpoint);
// Assert
Assert.NotNull(result);
Assert.Equal(expectedResponse.Message, ((dynamic)result).Message);
}
[Fact]
public async Task GetAsync_ShouldThrowException_WhenServiceIsNotAvailable()
{
// Arrange
var serviceName = "NonExistentService";
var endpoint = "/api/test";
// 模拟 Nacos 服务发现返回 null
_nacosNamingServiceMock.Setup(x => x.SelectOneHealthyInstance(serviceName)).ReturnsAsync((Instance)null);
// Act & Assert
await Assert.ThrowsAsync<Exception>(() => _serviceClient.GetAsync<object>(serviceName, endpoint));
}
[Fact]
public async Task GetAsync_ShouldHandleDifferentEndpointFormats()
{
// Arrange
var serviceName = "TestService";
var expectedResponse = new { Message = "Test Response" };
// 模拟 Nacos 服务发现返回一个健康的实例
var instance = new Instance
{
Ip = "127.0.0.1",
Port = 8080,
Healthy = true
};
_nacosNamingServiceMock.Setup(x => x.SelectOneHealthyInstance(serviceName)).ReturnsAsync(instance);
// 创建测试服务器
var testServer = new TestServer(new WebApplicationFactory<object>().WithWebHostBuilder(builder =>
{
builder.Configure(app =>
{
app.Run(async context =>
{
// 验证请求路径是否以 '/' 开头
Assert.StartsWith("/", context.Request.Path);
await context.Response.WriteAsJsonAsync(new { StatusCode = 200, Message = "Success", Data = expectedResponse });
});
});
}));
// 测试不同格式的端点
var endpoints = new[] { "/api/test", "api/test", "test", "/test" };
foreach (var endpoint in endpoints)
{
// Act & Assert
var result = await _serviceClient.GetAsync<object>(serviceName, endpoint);
Assert.NotNull(result);
}
}
[Fact]
public async Task PostAsync_ShouldReturnSuccess_WhenServiceIsAvailable()
{
// Arrange
var serviceName = "TestService";
var endpoint = "/api/test";
var requestData = new { Name = "Test" };
var expectedResponse = new { Message = "Test Response" };
// 模拟 Nacos 服务发现返回一个健康的实例
var instance = new Instance
{
Ip = "127.0.0.1",
Port = 8080,
Healthy = true,
Enabled = true
};
_nacosNamingServiceMock.Setup(x => x.SelectOneHealthyInstance(serviceName)).ReturnsAsync(instance);
// 创建一个测试服务器
var testServer = new TestServer(new WebApplicationFactory<object>().WithWebHostBuilder(builder =>
{
builder.Configure(app =>
{
app.MapPost("/api/test", (object data) => Results.Ok(expectedResponse));
});
}));
// 使用测试服务器的 HttpClient
var testHttpClient = testServer.CreateClient();
var testServiceClient = new ServiceClient(_nacosNamingServiceMock.Object, testHttpClient, _loggerMock.Object);
// Act
var result = await testServiceClient.PostAsync<object>(serviceName, endpoint, requestData);
// Assert
Assert.NotNull(result);
Assert.Equal(expectedResponse.Message, ((dynamic)result).Message);
}
[Fact]
public async Task PutAsync_ShouldReturnSuccess_WhenServiceIsAvailable()
{
// Arrange
var serviceName = "TestService";
var endpoint = "/api/test";
var requestData = new { Name = "Test" };
var expectedResponse = new { Message = "Test Response" };
// 模拟 Nacos 服务发现返回一个健康的实例
var instance = new Instance
{
Ip = "127.0.0.1",
Port = 8080,
Healthy = true,
Enabled = true
};
_nacosNamingServiceMock.Setup(x => x.SelectOneHealthyInstance(serviceName)).ReturnsAsync(instance);
// 创建一个测试服务器
var testServer = new TestServer(new WebApplicationFactory<object>().WithWebHostBuilder(builder =>
{
builder.Configure(app =>
{
app.MapPut("/api/test", (object data) => Results.Ok(expectedResponse));
});
}));
// 使用测试服务器的 HttpClient
var testHttpClient = testServer.CreateClient();
var testServiceClient = new ServiceClient(_nacosNamingServiceMock.Object, testHttpClient, _loggerMock.Object);
// Act
var result = await testServiceClient.PutAsync<object>(serviceName, endpoint, requestData);
// Assert
Assert.NotNull(result);
Assert.Equal(expectedResponse.Message, ((dynamic)result).Message);
}
[Fact]
public async Task DeleteAsync_ShouldReturnSuccess_WhenServiceIsAvailable()
{
// Arrange
var serviceName = "TestService";
var endpoint = "/api/test";
var expectedResponse = new { Message = "Test Response" };
// 模拟 Nacos 服务发现返回一个健康的实例
var instance = new Instance
{
Ip = "127.0.0.1",
Port = 8080,
Healthy = true,
Enabled = true
};
_nacosNamingServiceMock.Setup(x => x.SelectOneHealthyInstance(serviceName)).ReturnsAsync(instance);
// 创建一个测试服务器
var testServer = new TestServer(new WebApplicationFactory<object>().WithWebHostBuilder(builder =>
{
builder.Configure(app =>
{
app.MapDelete("/api/test", () => Results.Ok(expectedResponse));
});
}));
// 使用测试服务器的 HttpClient
var testHttpClient = testServer.CreateClient();
var testServiceClient = new ServiceClient(_nacosNamingServiceMock.Object, testHttpClient, _loggerMock.Object);
// Act
var result = await testServiceClient.DeleteAsync<object>(serviceName, endpoint);
// Assert
Assert.NotNull(result);
Assert.Equal(expectedResponse.Message, ((dynamic)result).Message);
}
}
}