私はこのような何かが役立つだろういくつかの機会がありました。たとえば、AccountCreator
をとるCreate
メソッドを持つNewAccount
があります。私のAccountCreator
にはIRepository
があり、最終的にはアカウントの作成に使用されます。私のAccountCreator
は最初にプロパティをNewAccount
からAccount
にマップし、次にAccount
をリポジトリに渡して最終的に作成します。私のテストは次のようになります。
public class when_creating_an_account
{
static Mock<IRepository> _mockedRepository;
static AccountCreator _accountCreator;
static NewAccount _newAccount;
static Account _result;
static Account _account;
Establish context = () =>
{
_mockedRepository = new Mock<IRepository>();
_accountCreator = new AccountCreator(_mockedRepository.Object);
_newAccount = new NewAccount();
_account = new Account();
_mockedRepository
.Setup(x => x.Create(Moq.It.IsAny<Account>()))
.Returns(_account);
};
Because of = () => _result = _accountCreator.Create(_newAccount);
It should_create_the_account_in_the_repository = () => _result.ShouldEqual(_account);
}
したがって、必要なのはIt.IsAny<Account>
を置き換えるものです。これは、正しいアカウントが作成されたことを確認するのに役立ちません。驚くべきことは次のようなものです...
public class when_creating_an_account
{
static Mock<IRepository> _mockedRepository;
static AccountCreator _accountCreator;
static NewAccount _newAccount;
static Account _result;
static Account _account;
Establish context = () =>
{
_mockedRepository = new Mock<IRepository>();
_accountCreator = new AccountCreator(_mockedRepository.Object);
_newAccount = new NewAccount
{
//full of populated properties
};
_account = new Account
{
//matching properties to verify correct mapping
};
_mockedRepository
.Setup(x => x.Create(Moq.It.IsLike<Account>(_account)))
.Returns(_account);
};
Because of = () => _result = _accountCreator.Create(_newAccount);
It should_create_the_account_in_the_repository = () => _result.ShouldEqual(_account);
}
It.IsAny<>
をIt.IsLike<>
に変更し、入力されたAccount
オブジェクトを渡したことに注意してください。理想的には、バックグラウンドで、何かがプロパティ値を比較し、それらがすべて一致する場合は通過させます。
それで、それはすでに存在しますか?それとも、これは以前に行ったことがあるので、コードを共有してもかまいませんか?
同様の基準に基づいて特定の値を返すようにリポジトリをスタブ化するには、次のように機能する必要があります。
_repositoryStub
.Setup(x => x.Create(
Moq.It.Is<Account>(a => _maskAccount.ToExpectedObject().Equals(a))))
.Returns(_account);
以下があなたのために働くはずです:
Moq.It.Is<Account>(a=>a.Property1 == _account.Property1)
ただし、前述のとおり、一致基準を実装する必要があります。
質問に記載されていることを正確に実行するものを見つけることができませんでした。それまでの間、モックメソッドに引数として渡されたオブジェクトの検証を処理するために私が見つけることができる最善の方法は(参照の平等の贅沢なしで)Callback
と期待されるオブジェクトパターンの組み合わせで実際の期待されるオブジェクトで:
public class when_creating_an_account
{
static Mock<IRepository> _mockedRepository;
static AccountCreator _accountCreator;
static NewAccount _newAccount;
static Account _result;
static Account _expectedAccount;
static Account _actualAccount;
Establish context = () =>
{
_mockedRepository = new Mock<IRepository>();
_accountCreator = new AccountCreator(_mockedRepository.Object);
_newAccount = new NewAccount
{
//full of populated properties
};
_expectedAccount = new Account
{
//matching properties to verify correct mapping
};
_mockedRepository
.Setup(x => x.Create(Moq.It.IsAny<Account>(_account)))
//here, we capture the actual account passed in.
.Callback<Account>(x=> _actualAccount = x)
.Returns(_account);
};
Because of = () => _result = _accountCreator.Create(_newAccount);
It should_create_the_account_in_the_repository =
() => _result.ShouldEqual(_account);
It should_create_the_expected_account =
() => _expectedAccount.ToExpectedObject().ShouldEqual(_actualAccount);
}
期待されるオブジェクトパターンは素晴らしいですが、C#で実装するのは複雑なので、私はそれらすべてを処理するライブラリを使用します。 https://github.com/derekgreer/expectedObjects
私の最後の観察では、渡された実際のアカウントのプロパティを調べ、それぞれを「期待されるオブジェクト」の同じプロパティと比較します。このように、私はモックプロパティチェックの膨大なリストを持っていませんし、テスト観測もたくさんありません。