13.1 单元测试与集成测试
单元测试:测试单个组件(如服务方法),隔离外部依赖(用 Moq 模拟),使用 xUnit 框架。
实战案例:单元测试 UserService:
- 创建单元测试项目:Visual Studio 新建 “xUnit 测试项目”,安装 NuGet 包:xunit、xunit.runner.visualstudio、Moq、Microsoft.EntityFrameworkCore。
- 编写单元测试:
public class UserServiceTests
{
private readonly Mock<AppDbContext> _mockDbContext;
private readonly IUserService _userService;
// 测试初始化(每个测试方法前执行)
public UserServiceTests()
{
// 1. 模拟DbContext和DbSet
var userData = new List<User>
{
new User { Id = 1, Name = "张三", Email = "zhangsan@test.com", Age = 25 },
new User { Id = 2, Name = "李四", Email = "lisi@test.com", Age = 30 }
}.AsQueryable();
var mockDbSet = new Mock<DbSet<User>>();
mockDbSet.As<IQueryable<User>>().Setup(m => m.Provider).Returns(userData.Provider);
mockDbSet.As<IQueryable<User>>().Setup(m => m.Expression).Returns(userData.Expression);
mockDbSet.As<IQueryable<User>>().Setup(m => m.ElementType).Returns(userData.ElementType);
mockDbSet.As<IQueryable<User>>().Setup(m => m.GetEnumerator()).Returns(userData.GetEnumerator());
// 2. 模拟DbContext
_mockDbContext = new Mock<AppDbContext>();
_mockDbContext.Setup(m => m.Users).Returns(mockDbSet.Object);
// 3. 注入模拟的DbContext到UserService
_userService = new UserService(_mockDbContext.Object);
}
// 测试1:GetUserNameByIdAsync返回正确姓名
[Fact]
public async Task GetUserNameByIdAsync_ExistingId_ReturnsCorrectName()
{
// Arrange:准备测试数据(已在构造函数中完成)
int userId = 1;
string expectedName = "张三";
// Act:执行待测试方法
var actualName = await _userService.GetUserNameByIdAsync(userId);
// Assert:验证结果
Assert.Equal(expectedName, actualName);
}
// 测试2:GetUserNameByIdAsync返回未知用户
[Fact]
public async Task GetUserNameByIdAsync_NonExistingId_ReturnsUnknown()
{
// Arrange
int userId = 99;
string expectedName = "未知用户";
// Act
var actualName = await _userService.GetUserNameByIdAsync(userId);
// Assert
Assert.Equal(expectedName, actualName);
}
}
- 运行测试:Visual Studio 测试资源管理器→运行所有测试,查看结果。
13.2 API 测试工具与自动化
- Postman:手动测试 API,支持保存测试用例、环境变量。
- 自动化 API 测试:用 xUnit+HttpClient 测试 API 端点,示例:
public class UserApiTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly HttpClient _client;
// 集成测试:使用WebApplicationFactory创建测试服务器
public UserApiTests(WebApplicationFactory<Program> factory)
{
_client = factory.CreateClient();
}
// 测试GET /api/v1/users
[Fact]
public async Task GetUsers_ReturnsSuccess()
{
// Act
var response = await _client.GetAsync("/api/v1/users?page=1&pageSize=10");
// Assert
response.EnsureSuccessStatusCode(); // 验证状态码200
var responseBody = await response.Content.ReadFromJsonAsync<PagedResult<UserDto>>();
Assert.NotNull(responseBody);
Assert.True(responseBody.Total >= 0);
}
// 测试POST /api/v1/users(需先登录获取Token)
[Fact]
public async Task CreateUser_ReturnsCreated()
{
// 1. 先登录获取Token
var loginRequest = new LoginRequest { UserName = "admin", Password = "123456" };
var loginResponse = await _client.PostAsJsonAsync("/api/auth/login", loginRequest);
loginResponse.EnsureSuccessStatusCode();
var loginResult = await loginResponse.Content.ReadFromJsonAsync<dynamic>();
string token = loginResult.Token;
// 2. 添加Token到请求头
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
// 3. 测试创建用户
var createRequest = new CreateUserRequest { Name = "王五", Email = "wangwu@test.com", Age = 28 };
var response = await _client.PostAsJsonAsync("/api/v1/users", createRequest);
// 4. 验证结果
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
var user = await response.Content.ReadFromJsonAsync<UserDto>();
Assert.Equal(createRequest.Name, user.Name);
}
}
13.3 容器化部署与 Docker
- Docker 部署流程:编写 Dockerfile→构建镜像→运行容器。
- 实战案例:Docker 部署ASP.NET Core API:
- 编写 Dockerfile(项目根目录):
# 阶段1:构建应用(使用SDK镜像)
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
# 复制项目文件
COPY ["MyWebApi.csproj", "."]
# 还原依赖
RUN dotnet restore "MyWebApi.csproj"
# 复制所有文件
COPY . .
# 构建发布版本
RUN dotnet build "MyWebApi.csproj" -c Release -o /app/build
RUN dotnet publish "MyWebApi.csproj" -c Release -o /app/publish /p:UseAppHost=false
# 阶段2:运行应用(使用 runtime 镜像,体积更小)
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app
# 从构建阶段复制发布文件
COPY --from=build /app/publish .
# 设置环境变量(生产环境)
ENV ASPNETCORE_ENVIRONMENT=Production
ENV ASPNETCORE_URLS=http://+:80
# 暴露端口
EXPOSE 80
# 启动应用
ENTRYPOINT ["dotnet", "MyWebApi.dll"]
- 构建 Docker 镜像:bash
docker build -t mywebapi:v1 .
- 运行 Docker 容器:bash
# 映射主机端口8080到容器端口80,挂载配置文件(可选)
docker run -d -p 8080:80 --name mywebapi-container mywebapi:v1
- 测试访问:访问http://localhost:8080/api/v1/users,或http://localhost:8080/swagger。
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END


















- 最新
- 最热
只看作者