メソッドをMoqでモックするときにメソッド引数のプロパティ値が設定されていることを確認するにはどうすればよいですか?
-
05-07-2019 - |
質問
以前に質問されたかどうかわからない場合は、ここに質問があります。
最初のコード:
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を割り当てたことを確認するにはどうすればよいですか
解決
実行できる方法はいくつかあります。必ずしも最適なソリューションではありませんが、既存の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();
}
}
もう少し良い解決策は、PasswordHashプロパティにIHasherインスタンスによって作成された値が割り当てられたことを確認できるように、SHA1Hasherを注入されたサービス(IHasherなど)に変えることです。
さらにAPIを開いて、PasswordHashプロパティを仮想化し、AddCustomerメソッドにMock Customerを渡して、プロパティが正しく設定されたことを確認できます。
他のヒント
SHA1Hasherを非静的および仮想にするか、またはISHA1Hasherインターフェースにラップしてから、モックすることができます。静的メソッドと静的オブジェクトをモック可能なクラスにラップすることは、テスト容易性を高める古典的な方法です。
所属していません StackOverflow