Не уверен, что об этом спрашивали раньше, вот в чем вопрос.

Сначала код:

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

Как я могу убедиться, что CustomerService присвоил PasswordHash перед передачей клиента в репозиторий?

1
Valentin V 26 Ноя 2009 в 15:34

2 ответа

Лучший ответ

Вы можете использовать несколько подходов. Хотя это не обязательно лучшее решение, вот одно, которое не требует от вас изменения существующего API. Предполагается, что SHA1Hasher.ComputeHash является общедоступным методом.

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

Немного лучшим решением было бы превратить SHA1Hasher во внедренную службу (такую ​​как IHasher), чтобы вы могли подтвердить, что свойству PasswordHash было присвоено значение, созданное экземпляром IHasher.

Еще больше открыв свой API, вы можете сделать свойство PasswordHash виртуальным, чтобы передать фиктивного клиента методу AddCustomer, чтобы убедиться, что свойство установлено правильно.

1
Mark Seemann 26 Ноя 2009 в 15:56

Вы можете сделать SHA1Hasher нестатическим и виртуальным или обернуть его в интерфейс ISHA1Hasher, который затем можно будет имитировать. Обертывание статических методов и объектов в имитируемые классы - классический способ повысить тестируемость.

0
mcintyre321 26 Ноя 2009 в 16:03