Soy nuevo en la unidad de pruebas, ¿alguien puede aconsejar cómo probar el método público (CreateUser) a continuación, utilizando xUnit y Moq, gracias!

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;
}

Privado siguientes métodos
Comprobar si el usuario existe simplemente devuelve el número de usuarios existentes

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

Hash Generación

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);
}

Sal Generaion

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();
}

Gracias,
J

EDITAR > 1

Esto es lo que tengo hasta ahora:

    [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 = "[email protected]",
        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


        }

Principal problema es que no tengo idea de cómo Simulacro, configurar el comportamiento del Método privado «CheckUserExists», como llama a IRepository que se burlaban de clase, por lo que será en este caso de regresar a mi simulacro de instalación para GetAllAsync de este método privado?

EDITAR 2

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

EDITAR > 3

[Fact]
public async void CreateUser_True()
{
  //arrange
  var users = new List<User>();
  users.Add(new User()
  {
    Email = "[email protected]",
    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 = "[email protected]"
  });

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

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

}
  • _userResolverService tiene que implementar una interfaz, de modo que usted puede burlarse de llamadas, por ejemplo: var _userResolverService = new IuserResolverService(); var controller = new userResolverServiceController(IuserResolverService.Object); IuserResolverService.SetUp(r => r.GetCustomerId). Returns (123); Seguir un simple ejemplo, hay cientos en línea.
InformationsquelleAutor sziszu | 2017-08-05

1 Comentario

  1. 7

    Como el método que está siendo probada async usted necesita para la instalación de todos los async dependencias para permitir que el método de flujo de finalización. Como para el método privado, desea configurar el comportamiento de las dependencias que se utilizan dentro de ese método, que en este caso es el de los usuarios del repositorio.

    [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 = "[email protected]",
            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 protected]",
            Password = "monkey123",
            //...other code removed for brevity
        });
    
        //assert
        Assert.IsTrue(actual);
        Assert.IsTrue(users.Count == 2);
        Assert.IsTrue(users.Any(u => u.CustomerId == 2);
    }

    Leer sobre Moq Inicio Rápido para obtener una mejor comprensión de cómo utilizar el marco de trabajo ficticios.

    • ¿Por qué la prueba de unidad de interfaz y burlándose de esta interfaz en el método de prueba de la misma? Lo que en realidad sucede es una prueba de la Maqueta no de una implementación concreta de un tipo que implementa la interfaz determinada. Un simulacro puede ser usado para pasar en un constructor de una clase concreta que se analiza para «simular» la funcionalidad dentro de esta clase de «romper dependencias» durante las pruebas. Así que un tipo de clase puede ser probado en forma aislada (sin más desconocido / no confiable funcionamiento de dependiente de interfaces y clases en la «clase de prueba»)
    • … Justo después de llegar a través de este: dontcodetired.com/blog/post/Mocking-in-NET-Core-Tests-with-Moq

Dejar respuesta

Please enter your comment!
Please enter your name here