带参数的模拟返回错误的结果

问题描述 投票:0回答:1

我需要测试一个方法,该方法接受一个名为

string
division
参数。我创建了一个模拟存储库。我在这个 repo 中有 3 个对象:其中 2 个带有
Division="NYC"
,1 个带有
Division="LAX"
。我将参数“NYC”传递给我的模拟,我想得到的回报是 2 个对象(我使用
Count
Shouldly
方法来断言它)。不幸的是,我得到一个错误,应该有 2 个但实际上是 3 个对象。当我对 db 再次调用 Hanndler 方法然后返回 2 个对象时,重要的是。参数传递有什么问题吗?

    // interface to mock
    public interface IUserRepository<UserDto>
    {
        Task<IReadOnlyList<UserDto>> ListAllActiveUsers(string division);
    }

    // Request
    public class GetUserListQuery : IRequest<List<UserListVm>>
    {
        public string Division { get; set; }
    }

    // Request Handler
    public class GetUserListQueryHandler : IRequestHandler<GetUserListQuery, List<UserListVm>>
    {
        //private readonly IAsyncRepository<UserDto> _asyncRepository;
        private readonly IUserRepository<UserDto> _userRepository;
        private readonly IMapper _mapper;

        public GetUserListQueryHandler(IUserRepository<UserDto> userRepository, IMapper mapper)
        {
            _userRepository = userRepository;
            _mapper = mapper;
        }


        public async Task<List<UserListVm>> Handle(GetUserListQuery request, CancellationToken cancellationToken)
        {
            var allUsers = (await _userRepository.ListAllActiveUsers(request.Division)).OrderBy(o => o.Id);
            return _mapper.Map<List<UserListVm>>(allUsers);
        }
    }


    // Repository mock
    public class UserRepositoryMocks
    {
        public static Mock<IUserRepository<UserDto>> GetUserRepository()
        {
            var users = new List<UserDto>
            {
                new UserDto
                {
                    Id = 1,
                    UserName = "Mike Smith",
                    Division = "NYC",
                    IsActive = true
                }, 
                
                new UserDto
                {
                    Id = 2,
                    UserName = "Rob Michael",
                    Division = "NYC",
                    IsActive = true
                },   
                
                new UserDto
                {
                    Id = 5,
                    UserName = "Carl Jackson",
                    Division = "LAX",
                    IsActive = true
                }
            };


            // Arrange
            var mockUserRepository = new Mock<IUserRepository<UserDto>>();

            mockUserRepository.Setup(repo => repo.ListAllActiveUsers(It.IsAny<string>())).ReturnsAsync(users);

            return mockUserRepository;
        }
    }



    // xUnit test
    public class GetUserListQueryHandlerTests
    {
        private readonly IMapper _mapper;
        private readonly Mock<IUserRepository<UserDto>> _mockUserRepository;

        public GetUserListQueryHandlerTests()
        {
            _mockUserRepository = UserRepositoryMocks.GetUserRepository();

            var configProvider = new MapperConfiguration(cfg =>
            {
                cfg.AddProfile<MappingProfile>();
                
            });

            _mapper = configProvider.CreateMapper();
        }

        [Fact]
        public async Task GetUsersListTest()
        {
            // Arrange
            var handler = new GetUserListQueryHandler(_mockUserRepository.Object, _mapper);

            // Act
            var result = await handler.Handle(new GetUserListQuery() { Division = "NYC" }, CancellationToken.None);

            // Assert
            result.ShouldBeOfType<List<UserListVm>>();
            result.Count.ShouldBe(2);
        }
    }
c# unit-testing asp.net-core xunit
1个回答
0
投票

你的模拟的问题是这一行:

mockUserRepository
  .Setup(repo => repo.ListAllActiveUsers(It.IsAny<string>()))
  .ReturnsAsync(users);

不管输入参数如何,它只是简单地返回一个

users
的列表。

更好的模拟是指定参数应该是什么:

mockUserRepository
  .Setup(repo => repo.ListAllActiveUsers("NYC"))  // narrow the call to just "NYC"
  .ReturnsAsync(users.Where(x => x.Division == "NYC")); // filter out irrelevant data
© www.soinside.com 2019 - 2024. All rights reserved.