带有 JdbcTemplate 自动装配的 SimpleJdbcCall 的 Junit

Posted

技术标签:

【中文标题】带有 JdbcTemplate 自动装配的 SimpleJdbcCall 的 Junit【英文标题】:Junit for SimpleJdbcCall with JdbcTemplate Autowired 【发布时间】:2021-05-20 17:11:12 【问题描述】:

我如何测试使用 JdbcTemplate 和 SimpleJdbcCall 的存储库类,如下所示

这是我尝试过的

下面是测试代码和仓库代码 我正在使用 Spring Boot 最新版本 junit 5 和 mockito。 我已尝试研究以下解决方案,但可以使其正常工作

Mockito for SimpleJdbcCall with Spring JdbcTemplate

@RunWith(MockitoJUnitRunner.class)
public class DataRepositoryTest 

    
    @InjectMocks
    private DataRepository dataRepository 
    
    
    @Mock
    private JdbcTemplate oracleJDBCTemplate;
    
     @Mock
     private SimpleJdbcCall simpleJdbcCall;
    
    
    
    @BeforeEach
    public void setup() 
        
        MockitoAnnotations.initMocks(this);
        
        simpleJdbcCall = new SimpleJdbcCall(oracleJDBCTemplate)
                .withProcedureName("PROC_NAME_P1")
                .withoutProcedureColumnMetaDataAccess()
                .declareParameters(
                           
                                new SqlParameter("p_in_name", Types.VARCHAR),
                                new SqlParameter("p_age", Types.VARCHAR)
                                
                        
                                ).returningResultSet("ref_cur", new DataRowMapper());
    
        
        

        
    
    
    @Test
    public void test()
    
        
        System.out.println(" JdbcTemplate-- "  + oracleJDBCTemplate ); // prints is oracleJDBCTemplate;
        
        System.out.println(" simpleJdbcCall-- "  + simpleJdbcCall ); //print object hascode

    


以下是存储库代码 @Repository 公共类 DataRepository

    @Autowired
    @Qualifier("OracleJDBCTemplate")
    private JdbcTemplate oracleJDBCTemplate;

    
    
    private SimpleJdbcCall simpleJdbcCall;
    
    
    @PostConstruct
    public void init()
    
        simpleJdbcCall = new SimpleJdbcCall(oracleJDBCTemplate)
                .withProcedureName("PROC_NAME_P1")
                .withoutProcedureColumnMetaDataAccess()
                .declareParameters(
                           
                                new SqlParameter("p_in_name", Types.VARCHAR),
                                new SqlParameter("p_age", Types.VARCHAR)
                                
                        
                                ).returningResultSet("ref_cur", new DataRowMapper());
        


                        

                
    

    @SuppressWarnings("unchecked")
    public List<Person>  getPerson(Data data) 
        

        
        
          Map<String, Object> result =
                  simpleJdbcCall.execute(date.getName,date.getAge);
          

          
          return (List<Person>) result.get("ref_cur");
      

【问题讨论】:

【参考方案1】:

您似乎在这里混合了 JUnit 4 和 JUnit Jupiter(JUnit 5 的一部分)。

@RunWith 是 JUnit 4(JUnit Jupiter 等价于 @ExtendWith(MockitoExtension.class) @BeforeEach 是 JUnit Jupiter

此外,当您想模拟它时,不要手动初始化您的simpleJdbcCall。当为您的DataRepository 编写单元测试并让 Mockito 为您创建被测类时,@PostConstruct 不会被调用,因此可以模拟所有协作者。

以下设置将模拟您的,您可以使用 Mockito 的 when().thenReturn() 来定义模拟的行为:

@ExendWith(MockitoExtension.class)
public class DataRepositoryTest 

    @InjectMocks
    private DataRepository dataRepository 
    
    @Mock
    private JdbcTemplate oracleJDBCTemplate;
    
    @Mock
    private SimpleJdbcCall simpleJdbcCall;

    @Test
    void test() 

    

【讨论】:

以上是关于带有 JdbcTemplate 自动装配的 SimpleJdbcCall 的 Junit的主要内容,如果未能解决你的问题,请参考以下文章

spring自动装配和aop的理解

自动化装配Bean

使用 Spring Security 的自动装配依赖注入

Spring学习系列 自动化装配Bean

Spring 3.2注释自动装配多个构造函数

从 jdbcTemplate 查询中只获取一行以进行性能优化