【发布时间】:2022-11-13 14:35:53
【问题描述】:
我正在尝试进行集成测试,控制器具有 IMediator,并且我正在使用 Moq 框架进行集成测试。
我遇到的问题是,在尝试模拟 MediatR 时,我的响应一直为空。在尝试模拟 MediatR 之前,我尝试模拟一个服务(在本例中为 IUserService)并且它运行良好(Delete 控制器和其他方法的返回类型是 bool)。
由于我现在在控制器中使用 IMediator,因此试图将集成测试更改为模拟 MediatR,因此我可以对具有 IUserService 的处理程序进行集成测试,但我正在尝试测试整个管道。下面是我从控制器到集成测试的代码。
//Controller
private IMediator _mediator;
public UserController(IMediator mediator)
{
_mediator = mediator;
}
[HttpDelete("{id}")]
public async Task<ActionResult<Result<Unit>>> DeleteUser(int id)
{
return await _mediator.Send(new DeleteUserCommand { UserId = id });
}
//Command handler
public class DeleteUserCommandHandler : IRequestHandler<DeleteUserCommand, Result<Unit>>
{
private readonly IUserService _userService;
public DeleteUserCommandHandler(IUserService userService)
{
_userService = userService;
}
public async Task<Result<Unit>> Handle(DeleteUserCommand request, CancellationToken cancellationToken)
{
return await _userService.DeleteUser(request.UserId);
}
}
//Service layer
public async Task<Result<Unit>> DeleteUser(int userId)
{
var userExist = await _context.Users.FirstOrDefaultAsync(x => x.Id == userId);
if (userExist == null) return Result<Unit>.Failure("User Id doesn't exsist");
_context.Remove(userExist);
var result = await _context.SaveChangesAsync() > 0;
return Result<Unit>.Success(Unit.Value);
}
//Integration test
[TestFixture]
public class UserControllerTests
{
private readonly Mock<IMediator> _mockMediator;
private UserController _userController;
public UserControllerTests()
{
_mockMediator = new Mock<IMediator>();
}
[Test]
public async Task DeleteUser_NotSuccessful_NoIdDeleted()
{
Result<Unit> expected = new Result<Unit>();
_mockMediator.Setup(x => x.Send(It.IsAny<DeleteUserCommand>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(expected));
_userController = new UserController(_mockMediator.Object);
var result = await _userController.DeleteUser(6);
Assert.AreEqual("User Id doesn't exsist", result?.Value?.Error);
}
}
//Response in the integration test
我有两个 UserId 6 和 7
UserId 6: 不存在,所以我期待一条消息说 id 不存在,但我得到的当前响应为空。
UserId 7: 确实存在并期待类似 IsSuccess: true 这是我添加的自定义代码
注意:附加的测试代码仅适用于用户 ID 6。
您可能会注意到,在上面从控制器开始的代码中,部分返回类型是 Result,它是我添加的自定义类,下面是代码。
public class Result<T>
{
public bool IsSuccess { get; set; }
public T Value { get; set; }
public string Error { get; set; }
public static Result<T> Success(T value) => new Result<T> { IsSuccess = true, Value = value };
public static Result<T> Failure(string error) => new Result<T> { IsSuccess = false, Error = error };
}
`
我试图找出我在模拟 MediatR 时做错了什么,以及为什么它一直返回 null。
我在这里先向您的帮助表示感谢。
我尝试进行集成测试的第一件事是模拟 IUserService,然后切换到 IMediator,然后在进行集成测试时开始在响应中获取 null。我试图用谷歌搜索这个问题,但没有运气。
【问题讨论】:
标签: c# api integration-testing moq mediatr