変更可能なエンティティを使用するサービスをテストする必要がある場合は、必要な最小のオブジェクト (実際のオブジェクト) を作成してサービスに渡します。例:
User joe = new User();
joe.setEmail("joe@example.com");
resetPasswordService.resetPassword(joe);
verif(emailServiceMock).sendEmail("joe@example.com", "Your password has been reset!");
明らかに User には多くのフィールドがありますが、resetPasswordService
必要ないので設定しません。メールではない User フィールドの名前を変更しても、このテストは変更されないため、これは非常にリファクタリングに適しています。
Immutablesオブジェクトで同じことをしようとすると、問題が発生します。同じ例に固執し、ユーザーをエンティティから不変に変えます。
@Value.Immutable
public abstract class User {
public abstract String getEmail();
public abstract PostalAddress getPostalAddress();
//more fields
}
User joe = new ImmutableUserBuilder().email("joe@example.com").build();
resetPasswordService.resetPassword(joe);
verif(emailServiceMock).sendEmail("joe@example.com", "Your password has been reset!");
java.lang.IllegalStateException: ユーザーを作成できません。必要な属性の一部が設定されていません [postalAddress、signupDate、city、....]
オブジェクトを構築しようとすると、これはビルダーで失敗します。それで、私は何をすべきですか?
- ユーザーにモックを使用し、モックがモックを返すたびに妖精が死んでもモックを返すようにします
- テスト用の DSL を作成し、必要のないすべてのフィールドを含むユーザー ツリー構造全体を構築するためのある種のファクトリを用意しますか? 重く、リファクタリングしにくいようです。これにより、テストの要件がそれほど透明ではなくなります。
- ユーザーのすべてのフィールドを作成
@Nullable
し、ビルダーにオブジェクトを検証させませんか? これにより、実稼働環境に不完全なオブジェクトが存在するリスクにさらされることになりますよね? - 私が逃した他のオプション?
ユーザーは不変の値オブジェクトではなく、エンティティであるべきだと私は知っています。分かりやすいので、この例では User を使用しました。