【问题标题】:How to do integration test with MediatR using Moq in C#?如何在 C# 中使用 Moq 与 MediatR 进行集成测试?
【发布时间】: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


    【解决方案1】:

    我是 c# 的初学者。我有类似的问题。我无法在单例类中使用 MediatR。我认为这是某种依赖注入问题。我只是一个初学者,这只是我的意见。别当真哈哈。

    【讨论】:

      猜你喜欢
      • 2019-12-17
      • 2017-01-19
      • 2016-11-12
      • 2023-01-04
      • 2019-08-12
      • 1970-01-01
      • 2011-12-24
      • 2021-10-15
      相关资源
      最近更新 更多