【发布时间】:2019-01-16 17:26:03
【问题描述】:
我正在尝试用 Mockito.spy 功能覆盖我的整个测试环境,所以只要我想我可以存根一个方法,但所有其他调用都使用默认功能。 这在 Service 层工作得很好,但我在 Repository 层遇到了问题。
我的设置如下:
Mockito - 2.15.0 春天 - 5.0.8 SpringBoot - 2.0.4
存储库:
public interface ARepository extends CrudRepository<ADBO, Long> {}
服务:
@Service
public class AService {
@Autowired
ARepository aRepository;
public ADBO getById(long id) {
return aRepository.findById(id).orElse(null);
}
public Iterable<ADBO> getAll() {
return aRepository.findAll();
}
}
间谍的配置:
@Profile("enableSpy")
@Configuration
public class SpyConfig {
@Bean
@Primary
public ARepository aRepository() {
return Mockito.spy(ARepository.class);
}
}
还有我的测试课:
@ActiveProfiles("enableSpy")
@RunWith(SpringRunner.class)
@SpringBootTest
public class AServiceTest {
@Autowired
AService aService;
@Autowired
ARepository aRepository;
@Test
public void test() {
ADBO foo = new ADBO();
foo.setTestValue("bar");
aRepository.save(foo);
doReturn(Optional.of(new ADBO())).when(aRepository).findById(1L);
System.out.println("result (1):" + aService.getById(1));
System.out.println("result all:" + aService.getAll());
}
}
现在这个测试有三种可能的结果:
- aRepository 既不是模拟也不是间谍:
org.mockito.exceptions.misusing.NotAMockException: Argument passed to when() is not a mock! Example of corr... aRepository 是模拟但不是间谍(这是我得到的结果):
result (1):ADBO(id=null, testValue=null) result all:[]aRepository 是一个间谍(这就是我想要的):
result (1):ADBO(id=null, testValue=null) result all:[ADBO(id=1, testValue=bar)]
我将此行为归因于存储库的spring实例化在后台更复杂,并且在调用Mockito.spy(ARepository.class)时未正确实例化存储库。
我还尝试将正确的实例自动装配到配置中,并使用@Autowired 对象调用Mockito.spy()。
这会导致:
Cannot mock/spy class com.sun.proxy.$Proxy75
Mockito cannot mock/spy because :
- final class
根据我的研究,从 v2.0.0 开始,Mockito 可以模拟和监视 final 类。
调用Mockito.mockingDetails(aRepository).isSpy() 返回true,这让我认为后台的对象没有正确实例化。
最后是我的问题:
如何使用 @Autowired 在我的 UnitTest 中获取 Spring-Data Repository 的间谍实例?
【问题讨论】:
-
为什么这么复杂?使用
@SpyBean注释您要监视的字段,而不是尝试将专用配置类硬塞到位。见docs.spring.io/spring-boot/docs/current/reference/html/… -
在 aRepository 上使用
@SpyBean而不是@Autowire会导致相同的行为,它变成模拟但不是间谍。 -
当docs.spring.io/spring-boot/docs/current/api/org/springframework/… spring boot 可以帮助您时,为什么还要花费如此多的精力和复杂性来围绕存储库进行测试?此外,这还需要您了解存储库的底层复杂性及其工作原理。
标签: java unit-testing spring-boot spring-data-jpa spy