我目前无法在同一测试类中使用*@Cacheble和@Mock/@InjectMocks*。
要清楚,因为使用了Mockito。verify(repository,times(1))我需要@Mock存储库并为存储库使用注解*@InjectMock*。这样做,我可以正确地验证应用程序的行为,但findById的结果不会被缓存。事实上,manager.get(cacheName)。get(key)将返回null。
相反,如果我使用@Autowired注解,值将被缓存,但verify(存储库,times(1))返回ZeroInteractions。我用调试器进行了检查,结果正常。
我应该如何让缓存存储和verify()都工作?为什么会这样?
- [我正在使用SpringBoot 2.1.3版本和Caffeine Cache Manager 3.1.1版]*
这是CacheManager类:
@Slf4j
@Configuration
@EnableCaching
public class CaffeineCacheConfig extends CachingConfigurerSupport {
@Bean("cacheManager")
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(generateCache());
return cacheManager;
}
}
这是缓存:
@Override
public CaffeineCache generateCache() {
return new CaffeineCache(name,
Caffeine.newBuilder()
.maximumSize(15)
.expireAfterWrite(60, TimeUnit.MINUTES)
.recordStats()
.build());
}
我有一个我试图缓存的服务,它是这样的:
@Service
@CacheConfig(cacheNames = CacheLocations.APPLICATION_LEVEL)
@Transactional(readOnly = true)
public class ApplicationLevelService implements IApplicationLevelService
{
@Autowired
private ApplicationLevelRepository repository;
@Autowired
private CacheManager manager;
@Override
@Cacheable
public ApplicationLevel findById(int id)
{
return repository.findById(id);
}
}
我试图用这个类(JUnit5)测试它:
@CacheConfig(cacheNames = {APPLICATION_LEVEL})
class ApplicationLevelCacheTest extends AbstractSpringTest
{
@InjectMocks
private ApplicationLevelService service;
@Mock
private ApplicationLevelRepository repository;
@Autowired
private CacheManager cacheManager;
@BeforeEach
void evictCache()
{
cacheManager.getCache(APPLICATION_LEVEL).clear();
}
@Nested
class TestApplicationLevelCache
{
@Test
@DisplayName("findAById() sets the resulting list in '" + CacheLocations.APPLICATION_LEVEL + "' cache")
void testApplicationLevelCaching_ApplicationLevelsAreCached_FindById()
{
when(repository.findById(anyInt())).thenReturn(Optional.of(new ApplicationLevel("mocked")));
assertNotNull(cacheManager.getCache(CacheLocations.APPLICATION_LEVEL));
var expected = service.findById(1);
verify(repository, times(1)).findById(anyInt());
assertNotNull(cacheManager.getCache(APPLICATION_LEVEL).get(1));
// should be cached
var actual = service.findById(1);
verifyZeroInteractions(repository);
assertEquals(expected, actual);
}
}
}
其中AbstractSpringTest只是包含以下内容的类:
- @SpringJUnitConfig
- @Spring启动测试()
- @ActiveProfiles(“测试”)
1条答案
按热度按时间o4tp2gmn1#
verify()
方法可用于验证已与Mockito进行模拟的bean的交互次数。使用
@Autowired
注解,您已经通过使用Spring的D.I.直接从Spring容器获取bean来初始化bean。您的cacheManager
对象位于Mockito的上下文之外。它并没有被Mockito嘲笑。我认为可以通过在
cacheManager
对象上使用@Spy
注解来解决这个问题。@Spy
和@Mock
都可以用于模拟字段。不同之处在于,使用@Mock
注解,您可以创建一个完整的模拟或虚拟对象,而使用m1n 8o1p,您可以拥有真实对象,并且可以直接调用或模拟其特定方法。您可以尝试使用:
希望能有所帮助。