在我的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);
}
}
当我在单元测试中使用@Autowired
为LabelServiceImpl
时,我得到">空指针异常"错误。如果我为该实例使用@InjectMocks
注释,则没有错误,但没有缓存完成(它调用labelService.findByUuid
2次而不是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);
}
}
这是