Comment vérifier que les valeurs de propriété de cet argument de méthode sont définies lors du mockage de méthodes avec Moq?

StackOverflow https://stackoverflow.com/questions/1803433

  •  05-07-2019
  •  | 
  •  

Question

Vous ne savez pas si cela a déjà été demandé, voici la question.

Code d'abord:

    public class Customer {
        public string Password { get; set; }
        public string PasswordHash { get; set; }
    }
    public class CustomerService {
        private ICustomerRepository _repo;

        public CustomerService(ICustomerRepository repo) {
            _repo = repo;
        }

        public int? AddCustomer(Customer customer) {
            customer.PasswordHash = SHA1Hasher.ComputeHash(customer.Password);
            return _repo.Add(customer);
        }
    }

    public interface ICustomerRepository {
        int? Add(Customer c);
    }
    public class CustomerRepository : ICustomerRepository {
        int? AddCustomer(Customer customer) {
            // call db and return identity
            return 1;
        }
    }

    [TestClass]
    public class CustomerServiceTest {
        [TestMethod]
        public void Add_Should_Compute_Password_Hash_Before_Saving() {
            var repoMock = new Mock<ICustomerRepository>();
            //how do I make sure the password hash was calculated before       passing the customer to repository???
        }
    }

Comment vérifier que CustomerService a attribué le PasswordHash avant de transférer le client au référentiel?

Était-ce utile?

La solution

Il existe plusieurs approches possibles. Bien que ce ne soit pas nécessairement la meilleure solution, voici une solution qui ne vous oblige pas à modifier votre API existante. Il suppose que SHA1Hasher.ComputeHash est une méthode publique.

[TestClass]
public class CustomerServiceTest
{
    [TestMethod]
    public void Add_Should_Compute_Password_Hash_Before_Saving()
    {
        var customer = new Customer { Password = "Foo" };
        var expectedHash = SHA1Hasher.ComputeHash(customer.Password);

        var repoMock = new Mock<ICustomerRepository>();
        repoMock
            .Setup(r => r.Add(It.Is<Customer>(c => c.PasswordHash == expectedHash)))
            .Returns(1)
            .Verifiable();

        // invoke service with customer and repoMock.Object here...

        repoMock.Verify();
    }
}

Une solution légèrement meilleure consisterait à transformer SHA1Hasher en un service injecté (tel que IHasher) afin de confirmer que la propriété PasswordHash s'est vue attribuer la valeur créée par l'instance IHasher.

En ouvrant encore plus votre API, vous pouvez rendre la propriété PasswordHash virtuelle afin de pouvoir passer un client fictif à la méthode AddCustomer afin de vérifier que la propriété a été correctement définie.

Autres conseils

Vous pouvez rendre SHA1Hasher non statique et virtuel ou l’envelopper dans une interface ISHA1Hasher qui peut ensuite être simulée. Envelopper des méthodes et des objets statiques dans des classes modifiables est un moyen classique d’augmenter la testabilité.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top