【问题标题】:How to call real methods of jpa repository in Junit5 mockito test cases for springboot services如何在Junit5 mockito测试用例中为springboot服务调用jpa存储库的真实方法
【发布时间】:2021-11-30 18:52:40
【问题描述】:

我有以下存储库接口,该接口正在我的服务类中使用。

@Repository
public interface InventoryRepository extends JpaRepository<Inventory, Integer> {    
        Inventory findByInventoryIdAndCompanyId(Integer inventoryId, Integer companyId);   
    }

在我的服务测试类中,我有这两个依赖项

 @InjectMocks
 InventoryService inventoryService;
        
 @Mock
 InventoryRepository inventoryRepository;

另外,下面是我在同一个类中的测试方法

 @Test
 public void getInventoryByIdTest() {
        when(inventoryRepository.findByInventoryIdAndCompanyId(16591,1)).thenCallRealMethod();
        Assertions.assertEquals(16591,inventoryService.getInventoryById(16591 , 1).getInventoryId());
    }

我正在尝试为服务编写测试用例,该服务在内部调用 JPA 存储库方法以从 DB 获取数据。我想调用 JPA 存储库的真实方法,并且我想获得真实的数据库结果而不是模拟它。但它不起作用并引发以下错误。

org.mockito.exceptions.base.MockitoException: 
Cannot call abstract real method on java object!
Calling real methods is only possible when mocking non abstract method.
//correct example:
when(mockOfConcreteClass.nonAbstractMethod()).thenCallRealMethod();

有什么办法可以解决吗?

【问题讨论】:

  • 既然你提到它是一个springboot服务,你需要确保首先加载spring上下文。您拥有的模拟不会加载弹簧上下文。示例 - baeldung.com/…

标签: spring-boot spring-data-jpa mockito junit5 powermockito


【解决方案1】:

让我们尝试将接口InventoryService 替换为您的junit 中的实现,并使用@Spy 而不是@Mock

提示

您的测试是集成测试,而不是单元测试。您正在测试您的应用程序与您的数据库没有任何问题的通信; 不幸的是,这种类型的测试需要很多资源和太多时间(让我们想象一下有大量的测试,并且每一个都打开到数据库的连接)。单元测试对于验证应用程序的业务逻辑很有用,因为它们不需要大量资源,如果它们需要,我们可以使用模拟接口或服务或其他任何东西,每次测试它们应该花费不到一秒.

建议你阅读 Martin Flower 的this of article

【讨论】:

    猜你喜欢
    • 2021-11-28
    • 1970-01-01
    • 2021-11-28
    • 2018-07-30
    • 2021-02-10
    • 2021-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多