キャッシングなどの技術的な側面をテストする場合は、データベースをまったく使用しないでください。ここで何をテストしたいかを理解することが重要です。まったく同じ引数を使用した呼び出しでは、メソッド呼び出しが回避されるようにする必要があります。データベースに面するリポジトリは、このトピックとは完全に直交する側面です。
これが私がお勧めするものです:
- 宣言型キャッシングを構成する統合テストをセットアップします (または、実稼働構成から必要なビットとピースをインポートします。
- リポジトリのモック インスタンスを構成します。
- モックの予想される動作を設定するテスト ケースを作成し、メソッドを呼び出して、それに応じて出力を検証します。
サンプル
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class CachingIntegrationTest {
// Your repository interface
interface MyRepo extends Repository<Object, Long> {
@Cacheable("sample")
Object findByEmail(String email);
}
@Configuration
@EnableCaching
static class Config {
// Simulating your caching configuration
@Bean
CacheManager cacheManager() {
return new ConcurrentMapCacheManager("sample");
}
// A repository mock instead of the real proxy
@Bean
MyRepo myRepo() {
return Mockito.mock(MyRepo.class);
}
}
@Autowired CacheManager manager;
@Autowired MyRepo repo;
@Test
public void methodInvocationShouldBeCached() {
Object first = new Object();
Object second = new Object();
// Set up the mock to return *different* objects for the first and second call
Mockito.when(repo.findByEmail(Mockito.any(String.class))).thenReturn(first, second);
// First invocation returns object returned by the method
Object result = repo.findByEmail("foo");
assertThat(result, is(first));
// Second invocation should return cached value, *not* second (as set up above)
result = repo.findByEmail("foo");
assertThat(result, is(first));
// Verify repository method was invoked once
Mockito.verify(repo, Mockito.times(1)).findByEmail("foo");
assertThat(manager.getCache("sample").get("foo"), is(notNullValue()));
// Third invocation with different key is triggers the second invocation of the repo method
result = repo.findByEmail("bar");
assertThat(result, is(second));
}
}
ご覧のとおり、ここでは少し過剰なテストを行っています。
- 最も関連性の高いチェックは、2 番目の呼び出しが最初のオブジェクトを返すことだと思います。それがキャッシングのすべてです。同じキーを使用した最初の 2 つの呼び出しは同じオブジェクトを返しますが、異なるキーを使用した 3 番目の呼び出しは、リポジトリでの 2 番目の実際の呼び出しになります。
- キャッシュに最初のキーの値が実際にあることを確認することで、テスト ケースを強化します。それを拡張して、実際の値を確認することもできます。一方で、アプリケーション レベルの動作ではなく、メカニズムの内部をテストする傾向があるため、それを避けても問題ないと思います。
重要ポイント
- コンテナーの動作をテストするためにインフラストラクチャを用意する必要はありません。
- テスト ケースの設定は簡単で簡単です。
- 適切に設計されたコンポーネントを使用すると、単純なテスト ケースを記述でき、テストのための統合作業が少なくて済みます。