当监视调用 save 方法的 JPARepository 时返回 null

Posted

技术标签:

【中文标题】当监视调用 save 方法的 JPARepository 时返回 null【英文标题】:When Spying on a JPARepository calling the save method returns null 【发布时间】:2019-06-30 07:18:23 【问题描述】:

我正在编写一个 SpringBoot 集成测试,我需要能够模拟与外部服务的交互,同时使用一些真实对象(如扩展 JPARepository 的接口)与我的数据库交互。

假设我的测试类如下,

@Service
class MyService 
     @Autowired
     MyRepository myRepository; // This is the JPARepository which I want to use the real thing

     @Autowired
     OtherService otherService; // This one I really want to mock

     public class myMethod() 
         //Code which composes anEntity
         //anEntity is not null
         MyEntity myEntity = myRepository.save(anEntity); //after save myEntity is null
         myEntity.getId(); // this will throw an NPE
     

现在这是我的测试课,

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
class MyServiceTest 
    @InjectMocks
    MyService service;

    @Spy
    @Autowired
    MyRepository myRepository;

    @Mock
    OtherService otherService

    public void testMyMethod() 
        myService.myMethod();
    

基本上注入 mocks 和 spys 似乎一切正常,但由于某种原因,当我在 MyRepository 上调用 save 时,它​​返回一个空对象而不是实体。

有没有办法解决这个问题?

【问题讨论】:

【参考方案1】:

不用上面的构造,只需使用 Spring Boot 原生注解 @SpyBean 你还需要自动装配测试类,在这种情况下是 MyService

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
class MyServiceTest 
    @SpyBean
    MyRepository myRepository;

    @Autowired
    OtherService otherService

    public void testMyMethod() 
        myService.myMethod();
    

【讨论】:

this stack question 提供有关 Spy 和 SpyBean 之间差异的更多信息

以上是关于当监视调用 save 方法的 JPARepository 时返回 null的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 spring4+spring-data-jpa(hibernateJpaVendorAdapter)+multidatasource+one entityManager+jpaReposit

多线程二(线程通信)

使用 Python Mock 库监视内部方法调用

监视 componentDidMount 中的方法调用

监视从组件的构造函数调用的方法

如何使用 Jest 监视方法调用?