### Question:
CampaignCacheClient { public Maybe<FetchEligibleCampaignsResponse> get() { Maybe<FetchEligibleCampaignsResponse> readFromCache = Maybe.fromCallable(() -> cachedResponse); Maybe<FetchEligibleCampaignsResponse> readFromStorage = storageClient .read(FetchEligibleCampaignsResponse.parser()) .doOnSuccess(response -> cachedResponse = response); return readFromCache .switchIfEmpty(readFromStorage) .filter(this::isResponseValid) .doOnError(s -> cachedResponse = null); } @Inject  CampaignCacheClient(
      @CampaignCache ProtoStorageClient storageClient, Application application, Clock clock); Completable put(FetchEligibleCampaignsResponse fetchEligibleCampaignsResponse); Maybe<FetchEligibleCampaignsResponse> get();  }### Answer:
@Test public void get_noInMemoryCache_fetchesFromStorage() { when(storageClient.read(FetchEligibleCampaignsResponse.parser())) .thenReturn(Maybe.just(fetchEligibleCampaignsResponse2)); TestSubscriber<FetchEligibleCampaignsResponse> subscriber = campaignCacheClient.get().toFlowable().test(); assertThat(getPlainValues(subscriber)).containsExactly(fetchEligibleCampaignsResponse2); }
@Test public void get_whenStorageCacheExpired_isEmpty() { when(storageClient.read(FetchEligibleCampaignsResponse.parser())) .thenReturn(Maybe.just(expiredCampaignResponse)); TestSubscriber<FetchEligibleCampaignsResponse> subscriber = campaignCacheClient.get().toFlowable().test(); subscriber.assertNoValues(); }
@Test public void get_whenBothCachesAreEmpty_isEmpty() { when(storageClient.read(FetchEligibleCampaignsResponse.parser())) .thenReturn(Maybe.error(new FileNotFoundException())); TestSubscriber<FetchEligibleCampaignsResponse> subscriber = campaignCacheClient.get().toFlowable().test(); subscriber.assertNoValues(); }