Spring Boot 2 - 使用Mockito测试@Cacheable没有参数的方法是行不通的

时间:2018-05-24 23:33:43

标签: java spring spring-boot mockito spring-cache

我有一个使用Spring Boot 2的应用程序。我想测试一个带有 @Cacheable (Spring Cache)的方法。我做了一个简单的例子来展示这个想法:

@Service
public class KeyService {

    @Cacheable("keyCache")
    public String getKey() {
        return "fakeKey";
    }
}

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest
public class KeyServiceTest {

    @Autowired
    private KeyService keyService;

    @Test
    public void shouldReturnTheSameKey() {

        Mockito.when(keyService.getKey()).thenReturn("key1", "key2");

        String firstCall = keyService.getKey();
        assertEquals("key1", firstCall);

        String secondCall = keyService.getKey();
        assertEquals("key1", secondCall);
    }

    @EnableCaching
    @Configuration
    static class KeyServiceConfig {

        @Bean
        KeyService keyService() {
            return Mockito.mock(KeyService.class);
        }

        @Bean
        CacheManager cacheManager() {
            return new ConcurrentMapCacheManager("keyCache");
        }
    }
}

上面的例子不起作用。但是,如果我更改getKey()方法以接收参数:

@Service
public class KeyService {

    @Cacheable("keyCache")
    public String getKey(String param) {
        return "fakeKey";
    }
}

重构测试以适应这种变化,测试成功:

@RunWith(SpringRunner.class)
@SpringBootTest
public class KeyServiceTest {

    @Autowired
    private KeyService keyService;

    @Test
    public void shouldReturnTheSameKey() {

        Mockito.when(keyService.getKey(Mockito.anyString())).thenReturn("key1", "key2");

        String firstCall = keyService.getKey("xyz");
        assertEquals("key1", firstCall);

        String secondCall = keyService.getKey("xyz");
        assertEquals("key1", secondCall);
    }

    @EnableCaching
    @Configuration
    static class KeyServiceConfig { //The same code as shown above }
}

你们对这个问题有什么看法吗?

2 个答案:

答案 0 :(得分:1)

使用方法参数作为关键字执行高速缓存查找。这意味着您需要没有参数的方法的钥匙。试试这个@Cacheable(value = "keyCache", key = "#root.methodName")

答案 1 :(得分:0)

我想知道您是否遇到默认密钥生成策略spring documentation的问题。这似乎是两者之间的最大区别。尽管我认为两者都应该起作用,但是它正在改变密钥的用途。