如何测试@Cacheable?

Gri*_*rim 10 java junit integration-testing spring-test

我正在努力在Spring Boot Integration Test中测试@Cacheable.这是我第二天学习如何进行集成测试以及我发现使用旧版本的所有示例.我还看到了一个例子assetEquals("some value", is())但没有任何一个import语句来知道哪个依赖"是"属于哪个.测试在第二次失败

这是我的集成测试....

@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");
    }
}
Run Code Online (Sandbox Code Playgroud)

ApplicationContext,组件,实体,存储库和服务层用于测试.我这样做的原因是因为这个maven模块在其他模块中用作依赖.

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

缓存配置....

@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());
    }
}
Run Code Online (Sandbox Code Playgroud)

正在测试的存储库....

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();
}
Run Code Online (Sandbox Code Playgroud)

Tob*_*tto 8

SettingRepositoryIT的第一个问题是在字段settingRepository上的@Mock 注释。这对于任何正常测试,集成测试或其他测试都是矛盾的。

您应该让Spring引入被测类(在您的情况下为SettingRepository)的依赖项。

请查看此示例,如何将@Autowired用于被测类,在本示例中为OrderService

@RunWith(SpringRunner.class)
// ApplicationContext will be loaded from the
// static nested Config class
@ContextConfiguration
public class OrderServiceTest {

    @Configuration
    static class Config {

        // this bean will be injected into the OrderServiceTest class
        @Bean
        public OrderService orderService() {
            OrderService orderService = new OrderServiceImpl();
            // set properties, etc.
            return orderService;
        }
    }

    @Autowired
    private OrderService orderService;

    @Test
    public void testOrderService() {
        // test the orderService
    }

}
Run Code Online (Sandbox Code Playgroud)

查阅带有完整示例的文档:§15.集成测试

第二个问题是您不必测试@Cachable。您应该只测试您的实现。这是来自Oliver Gierke的一个很好的示例,说明了如何测试它:如何在Spring Data存储库上测试Spring的声明式缓存支持?

  • “您不必测试Cachable”是不正确的,为了安全起见,我应该拥有测试Cachable的工具。如果没有,如何确定我所有的JPA缓存设置正确?所有需要的注释都到位了吗?所有的缓存bean在运行时都位于容器中吗?未经测试,我无法相信。无论如何,我将通过制作测试示例来测试是否可以通过Spring Test进行测试。我觉得无法使用SpringTest进行测试是一个缺点。 (3认同)