不确定之前是否有问题,这是问题。
代码优先:
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?
答案 0 :(得分:1)
您可以采取几种方法。虽然不一定是最佳解决方案,但这里不需要您更改现有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属性设置为虚拟,这样您就可以将Mock客户传递给AddCustomer方法以验证属性是否已正确设置。
答案 1 :(得分:0)
您可以将SHA1Hasher设置为非静态和虚拟,或者将其包装在ISHA1Hasher接口中,然后可以对其进行模拟。在可模拟类中包装静态方法和对象是提高可测试性的经典方法。