Java / Spring:不能在单元测试中测试缓存



在我的Java应用程序中,我试图用单元测试测试以下服务方法:

@Service
@EnableCaching
@RequiredArgsConstructor
public class LabelServiceImpl implements LabelService {
private static final String CACHE_NAME = "demoCache";
private final LabelRepository labelRepository;

@Override
public List<LabelDTO> findByUuid(UUID uuid) {
final Label label = labelRepository.findByUuid(uuid)
.orElseThrow(() -> new EntityNotFoundException("Not found."));
final List<LabelDTO> labelList = labelRepository.findByUuid(uuid);
return labelList;
}
}

这是我的单元测试:

@Import({CacheConfig.class, LabelServiceImpl.class})
@ExtendWith(SpringExtension.class)
@EnableCaching
@ImportAutoConfiguration(classes = {
CacheAutoConfiguration.class,
RedisAutoConfiguration.class
})
@RunWith(MockitoJUnitRunner.class)
public class CachingTest {
@InjectMocks
private LabelServiceImpl labelService;
@Autowired
private CacheManager cacheManager;

@Mock
private LabelRepository labelRepository;

@Test
void givenRedisCaching_whenFindUuid_thenReturnFromCache() {
//code omitted 

LabelDTO labelFromDb = labelService.findByUuid(uuid);
LabelDTO labelFromCache = labelService.findByUuid(uuid);
verify(labelRepository, times(1)).findByUuid(uuid);
}
}

当我在单元测试中使用@AutowiredLabelServiceImpl时,我得到">空指针异常"错误。如果我为该实例使用@InjectMocks注释,则没有错误,但没有缓存完成(它调用labelService.findByUuid2次而不是1次)。

我认为我犯了一个错误,与单元测试类的注释有关,但我尝试了许多不同的组合,仍然无法解决问题。

那么,我该如何解决这个问题呢?

更新:最后,我使用以下方法解决了这个问题。但是,我还必须将mockito-core版本从3.3.3更新到3.7.0,如下所示。否则我就会得到">java.lang。NoSuchMethodError: org.mockito.MockitoAnnotations.openMocks (Ljava/lang/对象;)Ljava/lang/AutoCloseable;"错误。

pom.xml:

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.7.0</version>
<scope>test</scope>
</dependency>

CachingTest:

@ExtendWith(MockitoExtension.class)
@SpringBootTest
public class CachingTest {
@Autowired
@InjectMocks
private LabelServiceImpl labelService;

@MockBean
private LabelRepository labelRepository;
@Test
public void givenRedisCaching_whenFindUuid_thenReturnFromCache() {
//code omitted 

LabelDTO labelFromDb = labelService.findByUuid(uuid);
LabelDTO labelFromCache = labelService.findByUuid(uuid);
verify(labelRepository, times(1)).findByUuid(uuid);
assertEquals(labelFromDb, labelFromCache);              
}
}

Mockito不模拟您的spring引导应用程序。它只是模拟带注释的对象,并将模拟对象注入到labelService中。

另一方面,测试spring启动应用程序@Autowired是不够的。

您必须构建一个Spring Boot集成测试。为此,用@SpringBootTest注释测试。这将初始化一个真正的应用程序上下文。

try autowire, LabelService

package com.demo;
import org.springframework.stereotype.Service;
@Service
public class LabelService
{
public String getLabel()
{
return "Test Label " + System.currentTimeMillis();
}
}
package com.demo;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class CachingTest
{
@Autowired
private LabelService labelService;
@Test
public void testLabelService()
{
assertNotNull(labelService);
}
}

这是

最新更新