我需要测试一个方法,该方法接受一个名为
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);
}
}
你的模拟的问题是这一行:
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