gpt4 book ai didi

c# - Xunit 和 Mock 数据与最小起订量

转载 作者:太空狗 更新时间:2023-10-29 22:57:01 24 4
gpt4 key购买 nike

我是单元测试的新手,任何人都可以建议如何使用 xUnit 和 Moq 测试下面的公共(public)方法 (CreateUser),谢谢!

public async Task<bool> CreateUser(UserDTO newUser)
{
newUser.CustomerId = _userResolverService.GetCustomerId();
if (await CheckUserExists(newUser)) return false;
var salt = GenerateSalt(10);
var passwordHash = GenerateHash(newUser.Password, salt);

await _usersRepository.AddAsync(new User()
{
Role = newUser.Role,
CretedOn = DateTime.Now,
CustomerId = newUser.CustomerId,
Email = newUser.Email,
FirstName = newUser.FirstName,
LastName = newUser.LastName,
PasswordHash = passwordHash,
Salt = salt,
UpdatedOn = DateTime.Now
});

return true;
}

下面的私有(private)方法检查用户是否存在只返回现有用户数

private async Task<bool> CheckUserExists(UserDTO user)
{
var users = await _usersRepository.GetAllAsync();
var userCount = users.Count(u => u.Email == user.Email);
return userCount > 0;
}

哈希生成

private static string GenerateHash(string input, string salt)
{
var bytes = System.Text.Encoding.UTF8.GetBytes(input + salt);
var sha256 = SHA256.Create();
var hash = sha256.ComputeHash(bytes);

return ByteArrayToString(hash);
}

盐世代

private static string GenerateSalt(int size)
{
var rng = RandomNumberGenerator.Create();
var buff = new byte[size];
rng.GetBytes(buff);
return Convert.ToBase64String(buff);
}



private static string ByteArrayToString(byte[] ba)
{
var hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}

谢谢,J

编辑 1

这是我目前所拥有的:

    [Fact]
public async void CreateUser_True()
{
//arrange
var dataSource = new Mock<IRepository<User, int>>();
var userResolverService = new Mock<IUserResolverService>();
var tokenService = new Mock<ITokenService>();

var users = new List<User>();
users.Add(new User()
{
Email = "test@test.com",
CustomerId = 1
});
dataSource.Setup(m => m.GetAllAsync()).ReturnsAsync(users); // Error Here with converting async task to IEnumerable...

var accountService = new AccountService(dataSource.Object,userResolverService.Object,tokenService.Object);


//act


//assert


}

主要问题是我不知道如何模拟、设置私有(private)方法“CheckUserExists”的行为,因为它正在调用针对类模拟的 IRepository,所以在这种情况下会从这个私有(private)方法返回我的 GetAllAsync 模拟设置方法?

编辑 2

public async Task<TEntity> AddAsync(TEntity entity)
{
if (entity == null)
{
throw new ArgumentNullException(nameof(entity));
}
_entities.Add(entity);
await _context.SaveChangesAsync();
return entity;
}

编辑 3

[Fact]
public async void CreateUser_True()
{
//arrange
var users = new List<User>();
users.Add(new User()
{
Email = "test@test.com",
CustomerId = 1
});
_dataSource.Setup(m => m.GetAllAsync()).ReturnsAsync(users);
_dataSource.Setup(m => m.AddAsync(It.IsAny<User>())).Returns<User>(Task.FromResult);
var accountService = new AccountService(_dataSource.Object, _userResolverService.Object, _tokenService.Object);


//act
var result = await accountService.CreateUser(new UserDTO()
{
Email = "truetest@test.com"
});

var updatedUsersList = await _dataSource.Object.GetAllAsync();
var usersCount = updatedUsersList.Count();

//assert
Assert.True(result);
Assert.Equal(2, usersCount);

}

最佳答案

由于被测试的方法是异步的,您需要设置所有异步依赖项以允许方法流完成。至于私有(private)方法,您想要设置该方法中使用的任何依赖项的行为,在本例中为用户存储库。

[Fact]
public async Task CreateUser_True() {
//arrange
var usersRepository = new Mock<IRepository<User, int>>();
var userResolverService = new Mock<IUserResolverService>();
var tokenService = new Mock<ITokenService>();

var user = new User() {
Email = "test@test.com",
CustomerId = 1
};
var users = new List<User>() { user };

usersRepository.Setup(_ => _.GetAllAsync()).ReturnsAsync(users);
usersRepository.Setup(_ => _.AddAsync(It.IsAny<User>()))
.Returns<User>(arg => Task.FromResult(arg)) //<-- returning the input value from task.
.Callback<User>(arg => users.Add(arg)); //<-- use call back to perform function
userResolverService.Setup(_ => _.GetCustomerId()).Returns(2);
var accountService = new AccountService(usersRepository.Object, userResolverService.Object, tokenService.Object);

//act
var actual = await accountService.CreateUser(new UserDto {
Email = "email@example.com",
Password = "monkey123",
//...other code removed for brevity
});

//assert
Assert.IsTrue(actual);
Assert.IsTrue(users.Count == 2);
Assert.IsTrue(users.Any(u => u.CustomerId == 2);
}

继续阅读 Moq Quickstart更好地了解如何使用模拟框架。

关于c# - Xunit 和 Mock 数据与最小起订量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45525519/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com