【问题标题】:Not able to mock connection.prepareCall method无法模拟 connection.prepareCall 方法
【发布时间】:2021-07-26 13:00:48
【问题描述】:

我无法模拟 connection.prepareCall("{call myStoreProcedure()}");调用 spring boot 项目。

每次我收到“org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "myStoreProcedure" not found; SQL statement:”,因为我使用的是 h2 数据库和我们没有那个程序。但是当我模拟它不应该调用数据库它应该只返回模拟值..但它没有发生。

注意:我已经超过了异常,但我的测试用例通过了。

下面是我的代码 sn-p :

package com.khan;

import static org.mockito.Mockito.mock;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
@PrepareForTest({ DataSource.class, Connection.class, CallableStatement.class })
@SpringBootTest
@PowerMockIgnore({ "javax.management.*", "javax.net.ssl.*", "javax.security.auth.*" })
@TestPropertySource({ "classpath:application.properties" })
public class MainClassTest {

    @Autowired
    MainClass mainClass;

    @Autowired
    private DataSource dataSource;
    
    @Test
    public void testMethod() throws Exception {
        ResultSet resultSet = mock(ResultSet.class);
        CallableStatement callableStatement = mock(CallableStatement.class);
        Mockito.when(dataSource.getConnection()).thenReturn(connection);
        Mockito.when(connection.prepareCall("{  call myprocedure()}")).thenReturn(callableStatement);
        Mockito.when(callableStatement.executeQuery()).thenReturn(resultSet);
        
        //Tried below one as well but no luck
        //PowerMockito.stub(PowerMockito.method(Connection.class, "prepareCall", Mockito.any())).toReturn(callableStatement);
        
        mainClass.callProcedure("Procedure Name");
    }

}

下面是我的 MainClass :

 public class MainClass{
    @Autowired
    private DataSource dataSource;
        
    public void callProcedure(String storedProcName) throws SQLException {
            Connection connection = dataSource.getConnection();
            try (CallableStatement cs = connection.prepareCall("{call " + storedProcName + "}");) { // I am getting exception here but test cases are passing
                cs.executeQuery();
            } catch (SQLException e) {
                log.error("Exception occured while execution of stored procedure having storedProcName: {} with reason: {} "
                        + e.getMessage(), storedProcName, e);
                throw e;
            }
    }
}

【问题讨论】:

    标签: spring spring-boot mockito powermock spring-boot-test


    【解决方案1】:

    我在您的测试用例中发现了很多问题。

    1. 不需要加载 Spring Context 来测试这个类。模拟就足够了。

    2. 在您的 callProcedure 中,您传递的是 "Procedure Name",但在模拟中,您期望 "{ call myprocedure()}" 以便永远不会触发模拟。 p>

    3. 您的测试用例通过了,因为您没有验证任何内容。

    试试下面的方法。

    @RunWith(PowerMockRunner.class)
    public class MainClassTest {
    
        @InjectMocks
        MainClass mainClass;
    
        @Mock
        private DataSource dataSource;
        
        @Test
        public void testMethod() throws Exception {
            //Given
            ResultSet resultSet = mock(ResultSet.class);
            CallableStatement callableStatement = mock(CallableStatement.class);
            Mockito.when(dataSource.getConnection()).thenReturn(connection);
            Mockito.when(connection.prepareCall(anyString())).thenReturn(callableStatement);
            Mockito.when(callableStatement.executeQuery()).thenReturn(resultSet);
            
            //When
            mainClass.callProcedure("Procedure Name");
    
            //Then
            verify(dataSource, times(1)).getConnection();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-11
      • 2019-01-30
      • 2020-03-04
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 2022-01-11
      相关资源
      最近更新 更多