如何验证使用Moq模拟方法时是否设置了方法参数的属性值?

时间:2009-11-26 12:34:27

标签: unit-testing mocking moq

不确定之前是否有问题,这是问题。

代码优先:

    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?

2 个答案:

答案 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接口中,然后可以对其进行模拟。在可模拟类中包装静态方法和对象是提高可测试性的经典方法。