CachedRepository implements Repository { @Override public synchronized RepositoryDTO fetchInstallableApplications() { if (cache == null) { cache = repository.fetchInstallableApplications(); } return cache; } CachedRepository(Repository repository); @Override synchronized RepositoryDTO fetchInstallableApplications(); @Override boolean isSafe(); @Override void onDelete(); void clearCache(); @Override boolean equals(Object o); @Override int hashCode();  }
@Test public void testFetchInstallableApplications() throws Exception { Repository repository = mock(Repository.class); when(repository .fetchInstallableApplications()) .thenReturn( new RepositoryDTO.Builder() .withTypes(Collections.singletonList( new TypeDTO.Builder() .withId("Type 1") .withCategories( Arrays.asList( new CategoryDTO.Builder().withId("Category 1") .build(), new CategoryDTO.Builder().withId("Category 2") .build())) .build())) .build()); final Repository cachedSource = new CachedRepository(repository); cachedSource.fetchInstallableApplications(); assertEquals(2, cachedSource.fetchInstallableApplications().getTypes().get(0).getCategories().size()); cachedSource.fetchInstallableApplications(); assertEquals(2, cachedSource.fetchInstallableApplications().getTypes().get(0).getCategories().size()); verify(repository, times(1)).fetchInstallableApplications(); }