IM/backend/IMTest/Service/FriendServiceTest.cs
西街长安 136199290b 后端:
新增好友请求事件和好友已添加事件
2026-02-01 13:21:21 +08:00

146 lines
4.7 KiB
C#

using AutoMapper;
using IM_API.Domain.Events;
using IM_API.Dtos;
using IM_API.Exceptions;
using IM_API.Models;
using IM_API.Services;
using MassTransit; // 必须引入
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Moq;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
public class FriendServiceTests
{
private readonly Mock<IPublishEndpoint> _mockEndpoint = new();
private readonly Mock<ILogger<FriendService>> _mockLogger = new();
#region
private ImContext CreateDbContext()
{
var options = new DbContextOptionsBuilder<ImContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString()) // 确保每个测试数据库隔离
.Options;
return new ImContext(options);
}
private IMapper CreateMapper()
{
var config = new MapperConfiguration(cfg =>
{
// 补充你业务中实际需要的映射规则
cfg.CreateMap<Friend, FriendInfoDto>();
cfg.CreateMap<FriendRequestDto, FriendRequest>();
cfg.CreateMap<FriendRequest, Friend>()
.ForMember(d => d.UserId, o => o.MapFrom(s => s.ResponseUser))
.ForMember(d => d.FriendId, o => o.MapFrom(s => s.RequestUser));
});
return config.CreateMapper();
}
private FriendService CreateService(ImContext context)
{
// 注入 Mock 对象和真实的 Mapper/Context
return new FriendService(context, _mockLogger.Object, CreateMapper(), _mockEndpoint.Object);
}
#endregion
[Fact]
public async Task SendFriendRequestAsync_Success_ShouldSaveAndPublish()
{
// Arrange
var context = CreateDbContext();
context.Users.AddRange(
new User { Id = 1, Username = "Sender", Password = "..." },
new User { Id = 2, Username = "Receiver", Password = "..." }
);
await context.SaveChangesAsync();
var service = CreateService(context);
var dto = new FriendRequestDto { ToUserId = 2, Description = "Hello" };
// Act
var result = await service.SendFriendRequestAsync(dto);
// Assert
Assert.True(result);
Assert.Single(context.FriendRequests);
// 验证事件是否发布到了 MQ
_mockEndpoint.Verify(x => x.Publish(
It.Is<RequestFriendEvent>(e => e.FromUserId == 1 && e.ToUserId == 2),
It.IsAny<CancellationToken>()),
Times.Once);
}
[Fact]
public async Task SendFriendRequestAsync_UserNotFound_ShouldThrow()
{
// Arrange
var context = CreateDbContext();
var service = CreateService(context);
var dto = new FriendRequestDto { ToUserId = 99 }; // 不存在的用户
// Act & Assert
await Assert.ThrowsAsync<BaseException>(() => service.SendFriendRequestAsync(dto));
}
[Fact]
public async Task SendFriendRequestAsync_AlreadyExists_ShouldThrow()
{
// Arrange
var context = CreateDbContext();
context.Users.Add(new User { Id = 2 });
context.FriendRequests.Add(new FriendRequest
{
RequestUser = 1,
ResponseUser = 2,
State = (sbyte)FriendRequestState.Pending
});
await context.SaveChangesAsync();
var service = CreateService(context);
// Act & Assert
await Assert.ThrowsAsync<BaseException>(() => service.SendFriendRequestAsync(new FriendRequestDto { ToUserId = 2 }));
}
[Fact]
public async Task BlockFriendAsync_ValidId_ShouldUpdateStatus()
{
// Arrange
var context = CreateDbContext();
var friend = new Friend { Id = 50, UserId = 1, FriendId = 2, StatusEnum = FriendStatus.Added };
context.Friends.Add(friend);
await context.SaveChangesAsync();
var service = CreateService(context);
// Act
await service.BlockeFriendAsync(50);
// Assert
var updated = await context.Friends.FindAsync(50);
Assert.Equal(FriendStatus.Blocked, updated.StatusEnum);
}
[Fact]
public async Task GetFriendListAsync_ShouldFilterByStatus()
{
// Arrange
var context = CreateDbContext();
context.Friends.AddRange(
new Friend { UserId = 1, FriendId = 2, StatusEnum = FriendStatus.Added },
new Friend { UserId = 1, FriendId = 3, StatusEnum = FriendStatus.Blocked }
);
await context.SaveChangesAsync();
var service = CreateService(context);
// Act
var result = await service.GetFriendListAsync(1, 1, 10, false);
// Assert
Assert.Single(result); // 只应该拿到 Added 状态的
}
}