HaniBlindBox/server/HoneyBox/tests/HoneyBox.Tests/Services/FinanceServiceTests.cs
2026-01-17 03:24:20 +08:00

419 lines
12 KiB
C#

using HoneyBox.Admin.Business.Models.Finance;
using HoneyBox.Admin.Business.Services;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Moq;
using Xunit;
namespace HoneyBox.Tests.Services;
/// <summary>
/// FinanceService 单元测试
/// </summary>
public class FinanceServiceTests : IDisposable
{
private readonly HoneyBoxDbContext _dbContext;
private readonly FinanceService _service;
private readonly Mock<ILogger<FinanceService>> _mockLogger;
public FinanceServiceTests()
{
var options = new DbContextOptionsBuilder<HoneyBoxDbContext>()
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
.Options;
_dbContext = new HoneyBoxDbContext(options);
_mockLogger = new Mock<ILogger<FinanceService>>();
_service = new FinanceService(_dbContext, _mockLogger.Object);
}
public void Dispose()
{
_dbContext.Dispose();
}
#region
[Fact]
public async Task GetConsumptionRanking_ShouldReturnUsersOrderedByConsumption()
{
// Arrange
SeedUsers(3);
SeedOrders();
var request = new FinanceQueryRequest { Page = 1, PageSize = 10 };
// Act
var result = await _service.GetConsumptionRankingAsync(request);
// Assert
Assert.NotNull(result);
Assert.True(result.List.Count > 0);
// 验证按消费金额降序排序
for (int i = 0; i < result.List.Count - 1; i++)
{
Assert.True(result.List[i].TotalConsumption >= result.List[i + 1].TotalConsumption);
}
}
[Fact]
public async Task GetConsumptionRanking_ShouldIncludeUserInfo()
{
// Arrange
SeedUsers(1);
SeedOrders();
var request = new FinanceQueryRequest { Page = 1, PageSize = 10 };
// Act
var result = await _service.GetConsumptionRankingAsync(request);
// Assert
Assert.NotNull(result);
if (result.List.Count > 0)
{
var first = result.List[0];
Assert.NotNull(first.Uid);
Assert.NotNull(first.Nickname);
}
}
#endregion
#region
[Fact]
public async Task GetBalanceDetails_ShouldReturnPaginatedResults()
{
// Arrange
SeedUsers(1);
SeedProfitMoney(15);
var request = new FinanceQueryRequest { Page = 1, PageSize = 10 };
// Act
var result = await _service.GetBalanceDetailsAsync(request);
// Assert
Assert.NotNull(result);
Assert.Equal(15, result.Total);
Assert.Equal(10, result.List.Count);
}
[Fact]
public async Task GetBalanceDetails_ShouldFilterByUserId()
{
// Arrange
SeedUsers(3);
SeedProfitMoneyForMultipleUsers();
var request = new FinanceQueryRequest { UserId = 1, Page = 1, PageSize = 20 };
// Act
var result = await _service.GetBalanceDetailsAsync(request);
// Assert
Assert.NotNull(result);
Assert.All(result.List, item => Assert.Equal(1, item.UserId));
}
[Fact]
public async Task GetBalanceDetails_ShouldFilterByDateRange()
{
// Arrange
SeedUsers(1);
SeedProfitMoneyWithDates();
var request = new FinanceQueryRequest
{
StartDate = DateTime.Today.AddDays(-3),
EndDate = DateTime.Today,
Page = 1,
PageSize = 20
};
// Act
var result = await _service.GetBalanceDetailsAsync(request);
// Assert
Assert.NotNull(result);
Assert.All(result.List, item =>
{
Assert.True(item.CreatedAt >= request.StartDate.Value.Date);
Assert.True(item.CreatedAt < request.EndDate.Value.Date.AddDays(1));
});
}
#endregion
#region
[Fact]
public async Task GetIntegralDetails_ShouldReturnPaginatedResults()
{
// Arrange
SeedUsers(1);
SeedProfitIntegral(10);
var request = new FinanceQueryRequest { Page = 1, PageSize = 5 };
// Act
var result = await _service.GetIntegralDetailsAsync(request);
// Assert
Assert.NotNull(result);
Assert.Equal(10, result.Total);
Assert.Equal(5, result.List.Count);
}
[Fact]
public async Task GetIntegralDetails_ShouldFilterByUserId()
{
// Arrange
SeedUsers(2);
SeedProfitIntegralForMultipleUsers();
var request = new FinanceQueryRequest { UserId = 2, Page = 1, PageSize = 20 };
// Act
var result = await _service.GetIntegralDetailsAsync(request);
// Assert
Assert.NotNull(result);
Assert.All(result.List, item => Assert.Equal(2, item.UserId));
}
#endregion
#region
[Fact]
public async Task GetScoreDetails_ShouldReturnPaginatedResults()
{
// Arrange
SeedUsers(1);
SeedProfitScore(8);
var request = new FinanceQueryRequest { Page = 1, PageSize = 5 };
// Act
var result = await _service.GetScoreDetailsAsync(request);
// Assert
Assert.NotNull(result);
Assert.Equal(8, result.Total);
Assert.Equal(5, result.List.Count);
}
#endregion
#region
[Fact]
public async Task GetRechargeRecords_ShouldReturnPaginatedResults()
{
// Arrange
SeedUsers(1);
SeedProfitPay(12);
var request = new FinanceQueryRequest { Page = 1, PageSize = 10 };
// Act
var result = await _service.GetRechargeRecordsAsync(request);
// Assert
Assert.NotNull(result);
Assert.Equal(12, result.Total);
Assert.Equal(10, result.List.Count);
}
[Fact]
public async Task GetRechargeRecords_ShouldIncludePayTypeName()
{
// Arrange
SeedUsers(1);
SeedProfitPay(1);
var request = new FinanceQueryRequest { Page = 1, PageSize = 10 };
// Act
var result = await _service.GetRechargeRecordsAsync(request);
// Assert
Assert.NotNull(result);
Assert.Single(result.List);
Assert.NotEmpty(result.List[0].PayTypeName);
}
#endregion
#region Helper Methods
private void SeedUsers(int count)
{
for (int i = 1; i <= count; i++)
{
_dbContext.Users.Add(new User
{
Id = i,
Uid = $"U{i:D3}",
Nickname = $"测试用户{i}",
Mobile = $"1380013800{i}",
OpenId = $"openid{i}",
HeadImg = $"http://test.com/head{i}.jpg",
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now
});
}
_dbContext.SaveChanges();
}
private void SeedOrders()
{
var orders = new[]
{
new Order { UserId = 1, OrderNum = "ORD001", Price = 100, UseMoney = 0, UseIntegral = 0, UseScore = 0, Status = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now, GoodsId = 1, GoodsTitle = "商品1", GoodsPrice = 100, OrderTotal = 100, OrderZheTotal = 100, Zhe = 1, Num = 1, PrizeNum = 1, Addtime = (int)DateTimeOffset.Now.ToUnixTimeSeconds() },
new Order { UserId = 1, OrderNum = "ORD002", Price = 200, UseMoney = 50, UseIntegral = 0, UseScore = 0, Status = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now, GoodsId = 1, GoodsTitle = "商品1", GoodsPrice = 200, OrderTotal = 200, OrderZheTotal = 200, Zhe = 1, Num = 1, PrizeNum = 1, Addtime = (int)DateTimeOffset.Now.ToUnixTimeSeconds() },
new Order { UserId = 2, OrderNum = "ORD003", Price = 500, UseMoney = 0, UseIntegral = 100, UseScore = 0, Status = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now, GoodsId = 1, GoodsTitle = "商品1", GoodsPrice = 500, OrderTotal = 500, OrderZheTotal = 500, Zhe = 1, Num = 1, PrizeNum = 1, Addtime = (int)DateTimeOffset.Now.ToUnixTimeSeconds() },
new Order { UserId = 3, OrderNum = "ORD004", Price = 50, UseMoney = 0, UseIntegral = 0, UseScore = 0, Status = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now, GoodsId = 1, GoodsTitle = "商品1", GoodsPrice = 50, OrderTotal = 50, OrderZheTotal = 50, Zhe = 1, Num = 1, PrizeNum = 1, Addtime = (int)DateTimeOffset.Now.ToUnixTimeSeconds() },
};
_dbContext.Orders.AddRange(orders);
_dbContext.SaveChanges();
}
private void SeedProfitMoney(int count)
{
for (int i = 1; i <= count; i++)
{
_dbContext.ProfitMoneys.Add(new ProfitMoney
{
UserId = 1,
ChangeMoney = 100 * i,
Money = 100 * i,
Type = 1,
Content = $"测试变动{i}",
ShareUid = 0,
CreatedAt = DateTime.Now
});
}
_dbContext.SaveChanges();
}
private void SeedProfitMoneyForMultipleUsers()
{
for (int userId = 1; userId <= 3; userId++)
{
for (int i = 1; i <= 5; i++)
{
_dbContext.ProfitMoneys.Add(new ProfitMoney
{
UserId = userId,
ChangeMoney = 100 * i,
Money = 100 * i,
Type = 1,
Content = $"用户{userId}变动{i}",
ShareUid = 0,
CreatedAt = DateTime.Now
});
}
}
_dbContext.SaveChanges();
}
private void SeedProfitMoneyWithDates()
{
for (int i = -10; i <= 0; i++)
{
_dbContext.ProfitMoneys.Add(new ProfitMoney
{
UserId = 1,
ChangeMoney = 100,
Money = 100,
Type = 1,
Content = $"日期测试{i}",
ShareUid = 0,
CreatedAt = DateTime.Today.AddDays(i)
});
}
_dbContext.SaveChanges();
}
private void SeedProfitIntegral(int count)
{
for (int i = 1; i <= count; i++)
{
_dbContext.ProfitIntegrals.Add(new ProfitIntegral
{
UserId = 1,
ChangeMoney = 50 * i,
Money = 50 * i,
Type = 1,
Content = $"积分变动{i}",
ShareUid = 0,
CreatedAt = DateTime.Now
});
}
_dbContext.SaveChanges();
}
private void SeedProfitIntegralForMultipleUsers()
{
for (int userId = 1; userId <= 2; userId++)
{
for (int i = 1; i <= 5; i++)
{
_dbContext.ProfitIntegrals.Add(new ProfitIntegral
{
UserId = userId,
ChangeMoney = 50 * i,
Money = 50 * i,
Type = 1,
Content = $"用户{userId}积分{i}",
ShareUid = 0,
CreatedAt = DateTime.Now
});
}
}
_dbContext.SaveChanges();
}
private void SeedProfitScore(int count)
{
for (int i = 1; i <= count; i++)
{
_dbContext.ProfitScores.Add(new ProfitScore
{
UserId = 1,
ChangeMoney = 10 * i,
Money = 10 * i,
Type = 1,
Content = $"钻石变动{i}",
ShareUid = 0,
CreatedAt = DateTime.Now
});
}
_dbContext.SaveChanges();
}
private void SeedProfitPay(int count)
{
for (int i = 1; i <= count; i++)
{
_dbContext.ProfitPays.Add(new ProfitPay
{
UserId = 1,
OrderNum = $"PAY{i:D5}",
ChangeMoney = 100 * i,
Content = $"充值{i}",
PayType = (byte)(i % 4),
CreatedAt = DateTime.Now
});
}
_dbContext.SaveChanges();
}
#endregion
}