J'ai du mal à tester @Cacheable dans un test d'intégration Spring Boot. C'est mon deuxième jour pour apprendre à faire des tests d'intégration et tous les exemples que j'ai trouvés utilisent des versions plus anciennes. J'ai également vu un exemple de assetEquals("some value", is())
mais rien avec une instruction d'importation pour savoir à quelle dépendance "appartient" appartient. Le test échoue à la seconde
Ceci est mon test d'intégration ....
@RunWith(SpringRunner.class)
@DataJpaTest // used for other methods
@SpringBootTest(classes = TestApplication.class)
@SqlGroup({
@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD,
scripts = "classpath:data/Setting.sql") })
public class SettingRepositoryIT {
@Mock
private SettingRepository settingRepository;
@Autowired
private Cache applicationCache;
@Test
public void testCachedMethodInvocation() {
List<Setting> firstList = new ArrayList<>();
Setting settingOne = new Setting();
settingOne.setKey("first");
settingOne.setValue("method invocation");
firstList.add(settingOne);
List<Setting> secondList = new ArrayList<>();
Setting settingTwo = new Setting();
settingTwo.setKey("second");
settingTwo.setValue("method invocation");
secondList.add(settingTwo);
// Set up the mock to return *different* objects for the first and second call
Mockito.when(settingRepository.findAllFeaturedFragrances()).thenReturn(firstList, secondList);
// First invocation returns object returned by the method
List<Setting> result = settingRepository.findAllFeaturedFragrances();
assertEquals("first", result.get(0).getKey());
// Second invocation should return cached value, *not* second (as set up above)
List<Setting> resultTwo = settingRepository.findAllFeaturedFragrances();
assertEquals("first", resultTwo.get(0).getKey()); // test fails here as the actual is "second."
// Verify repository method was invoked once
Mockito.verify(settingRepository, Mockito.times(1)).findAllFeaturedFragrances();
assertNotNull(applicationCache.get("findAllFeaturedFragrances"));
// Third invocation with different key is triggers the second invocation of the repo method
List<Setting> resultThree = settingRepository.findAllFeaturedFragrances();
assertEquals(resultThree.get(0).getKey(), "second");
}
}
ApplicationContext, composants, entités, référentiels et couche de service pour les tests. La raison pour laquelle je le fais de cette façon est que ce module maven est utilisé dans d'autres modules comme dépendance.
@ComponentScan({ "com.persistence_common.config", "com.persistence_common.services" })
@EntityScan(basePackages = { "com.persistence_common.entities" })
@EnableJpaRepositories(basePackages = { "com.persistence_common.repositories" })
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Configuration du cache ....
@Configuration
@EnableCaching
public class CacheConfig {
public static final String APPLICATION_CACHE = "applicationCache";
@Bean
public FilterRegistrationBean registerOpenSessionInViewFilterBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
OpenEntityManagerInViewFilter filter = new OpenEntityManagerInViewFilter();
registrationBean.setFilter(filter);
registrationBean.setOrder(5);
return registrationBean;
}
@Bean
public Cache applicationCache() {
return new GuavaCache(APPLICATION_CACHE, CacheBuilder.newBuilder()
.expireAfterWrite(30, TimeUnit.DAYS)
.build());
}
}
Le dépôt sous test ....
public interface SettingRepository extends JpaRepository<Setting, Integer> {
@Query(nativeQuery = true, value = "SELECT * FROM Setting WHERE name = 'featured_fragrance'")
@Cacheable(value = CacheConfig.APPLICATION_CACHE, key = "#root.methodName")
List<Setting> findAllFeaturedFragrances();
}
Dans mon cas, je voulais valider l'expression dans l'expression sauf dans l'annotation @Cacheable, donc je pense que c'est parfaitement logique et je ne teste pas le code de Spring.
J'ai réussi à le tester sans utiliser Spring Boot, il s'agit donc d'un simple test Spring:
@RunWith(SpringRunner.class)
@ContextConfiguration
public class MyTest {
@Configuration
@EnableCaching
static class Config {
@Bean
public MyCacheableInterface myCacheableInterface() {
return (authorization) -> createTestResult();
}
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("myObject");
}
}
@Autowired
private MyCacheableInterface myCacheableInterface;
Dans MyCacheableInterface, j'ai l'annotation suivante:
public interface MyCacheableInterface {
@Cacheable(value = "myObject", unless = "#result.?[Retorno.getSucesso() != 'S'].size() == #result.size()")
List<MyObject> businessMethod(String authorization);
}