I will translate the provided text, “Mockito OracleConnection,” as you requested.

huangapple go评论63阅读模式
英文:

Mockito OracleConnection

问题

以下是翻译的内容:

我正在尝试测试一个旧的纯Spring应用程序。我试图测试一个作为数据提供程序并使用OracleConnection的类。我在使用Mocikto进行测试,但每当执行与数据库连接相关的代码时,它就会抛出NPE(NullPointerException)。我知道我可以将parseSQLErrorDB更改为public,并进行类似Mockito.when.then的操作,但这不是重点。

我的测试代码:

public class DataProviderTest {
    
    @InjectMocks
    DataProvider dataProvider;
    
    @Mock
    PoolDataSource dataSource;
    
    @Mock
    OracleCallableStatement oracleCallableStatement;
    
    @BeforeEach
    public void setUp() throws SQLException {
        MockitoAnnotations.initMocks(this);
        ReflectionTestUtils.setField(dataProvider, "parseSQLErrorFuntion", "要注入的字符串");
        Mockito.when(dataSource.getConnection()).thenReturn(Mockito.any(Connection.class));
    }
    
    @Test
    public void parseSQLErrorUnconditionalTest() throws SQLException {
        String messageFromDB = "来自数据库的错误消息";
        String expected = messageFromDB;
        String actual = dataProvider.parseSQLError("未定义");
        Mockito.verify(oracleCallableStatement, Mockito.times(1)).execute();
        assertEquals(expected, actual);
    }
}

DataProvider类:

public class DataProvider {
    private static final Logger logger = LoggerFactory.getLogger(DataProvider.class);
    
    // private OracleDataSource dataSource;
    private PoolDataSource dataSource;
    private boolean isAthenticate;
    private String parseSQLErrorFuntion;
    private boolean isInitialized;
    private boolean ignoreMsgLenLimit;
    
    public DataProvider() {
        super();
    }
    
    @PostConstruct
    private void init() {
        OracleConnection conn = null;
        try {
            conn = (OracleConnection) dataSource.getConnection();
            loggerInfoAboutDatabase(conn);
            if (!testParseSQLErrorDB(conn)) {
                logger.warn("缺少:parseSQLErrorFuntion");
                parseSQLErrorFuntion = null;
            }
            isInitialized = true;
        } catch (SQLException ex) {
            logger.error("{}", ex.getMessage(), ex);
        } finally {
            closeConnection(null, conn);
        }
    }
    
    public String parseSQLError(String errorString) {
        if (errorString != null) {
            return parseSQLErrorDB(errorString);
        }
        return errorString;
    }
    
    private String parseSQLErrorDB(String errorString) {
        OracleCallableStatement cs = null;
        OracleConnection conn = null;
        String callS = "";
        try {
            conn = getConnection();
            // ...剩余的代码
        } catch (SQLException ex) {
            logger.error("Error parseSQLError: {} ; error: {}", callS, ex.getMessage());
        } finally {
            closeConnection(cs, conn);
        }
        return rv;
    }
    
    // ...其他方法
    
    private void loggerInfoAboutDatabase(Connection connection) throws SQLException {
        DatabaseMetaData dbMetaData = connection.getMetaData();
        logger.info("=============");
        logger.info("Database Product Name is : " + dbMetaData.getDatabaseProductName());
        logger.info("Database Product Version : " + dbMetaData.getDatabaseProductVersion());
        logger.info("JDBC Driver Name          : " + dbMetaData.getDriverName());
        logger.info("JDBC Driver Version is    : " + dbMetaData.getDriverVersion());
        logger.info("JDBC Driver Major Version : " + dbMetaData.getDriverMajorVersion());
        logger.info("JDBC Driver Minor Version : " + dbMetaData.getDriverMinorVersion());
        logger.info("=============");
    }
    
    // ...getter和setter方法
}

当我在setUp()块中执行以下代码时:

Mockito.when(dataSource.getConnection()).thenReturn(Mockito.any(Connection.class));

我得到了以下错误:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at pl.sygnity.common.db.DataProviderTest.setUp(DataProviderTest.java:47)
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
But when I comment this out, it executes methods and throws NPE on loggerInfoAboutDatabase method..
java.lang.NullPointerException
at pl.test.common.db.DataProvider.loggerInfoAboutDatabase(DataProvider.java:186)
at pl.test.common.db.DataProvider.init(DataProvider.java:49)
at pl.test.common.db.DataProvider.getConnection(DataProvider.java:146)
at pl.test.common.db.DataProvider.parseSQLErrorDB(DataProvider.java:90)
at pl.test.common.db.DataProvider.parseSQLError(DataProvider.java:74)
at pl.test.common.db.DataProviderTest.parseSQLErrorUnconditionalTest(DataProviderTest.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at ...

这里有什么想法吗?我能以某种方式伪造这个PoolDataSource和所有相关的内容吗?

英文:

I am trying to test old pure Spring app. I am trying to test class which is data provider and uses OracleConnection. I am using Mocikto for this but any time when database conection related code is executed it throws NPE. I know that i could change parseSQLErrorDB to public and do kind of Mockito.when.then but that is not the point..

My test:

public class DataProviderTest {
@InjectMocks
DataProvider dataProvider;
@Mock
PoolDataSource dataSource;
@Mock
OracleCallableStatement oracleCallableStatement;
@BeforeEach
public void setUp() throws SQLException {
MockitoAnnotations.initMocks(this);
ReflectionTestUtils.setField(dataProvider, "parseSQLErrorFuntion", "String you want to inject");
Mockito.when(dataSource.getConnection()).thenReturn(Mockito.any(Connection.class));
}
@Test
public void parseSQLErrorUnconditionalTest() throws SQLException {
String messageFromDB = "Error message from database";
String expected = messageFromDB;
String actual = dataProvider.parseSQLError("Undefined");
Mockito.verify(oracleCallableStatement, Mockito.times(1)).execute();
assertEquals(expected, actual);
}
}

And DataProvider:

public class DataProvider {
private static final Logger logger = LoggerFactory.getLogger(DataProvider.class);
// private OracleDataSource dataSource;
private PoolDataSource dataSource;
private boolean isAthenticate;
private String parseSQLErrorFuntion;
private boolean isInitialized;
private boolean ignoreMsgLenLimit;
public DataProvider() {
super();
}
@PostConstruct
private void init() {
OracleConnection conn = null;
try {
conn = (OracleConnection) dataSource.getConnection();
loggerInfoAboutDatabase(conn);
if (!testParseSQLErrorDB(conn)) {
logger.warn("Brak: parseSQLErrorFuntion");
parseSQLErrorFuntion = null;
}
isInitialized = true;
} catch (SQLException ex) {
logger.error("{}", ex.getMessage(), ex);
} finally {
closeConnection(null, conn);
}
}
public String parseSQLError(String errorString) {
if (errorString != null) {
return parseSQLErrorDB(errorString);
}
return errorString;
}
private String parseSQLErrorDB(String errorString) {
OracleCallableStatement cs = null;
OracleConnection conn = null;
String callS = "";
try {
conn = getConnection();
...rest of code
}
} catch (SQLException ex) {
logger.error("Error parseSQLError: {} ; error: {}", callS, ex.getMessage());
} finally {
closeConnection(cs, conn);
}
return rv;
}
public void close() {
}
public OracleConnection getConnection() throws SQLException {
...
}
public OracleConnection getConnection(String username, String password) throws SQLException {
...
}
public static void closeConnection(Connection conn) {
...
}
public static void closeConnection(CallableStatement cs, Connection conn) {
...
}
public static void closeConnection(Statement stmt, ResultSet rs, Connection conn) {
...
}
private void loggerInfoAboutDatabase(Connection connection) throws SQLException {
DatabaseMetaData dbMetaData = connection.getMetaData();
logger.info("=============");
logger.info("Database Product Name is : " + dbMetaData.getDatabaseProductName());
logger.info("Database Product Version : " + dbMetaData.getDatabaseProductVersion());
logger.info("JDBC Driver Name          : " + dbMetaData.getDriverName());
logger.info("JDBC Driver Version is    : " + dbMetaData.getDriverVersion());
logger.info("JDBC Driver Major Version : " + dbMetaData.getDriverMajorVersion());
logger.info("JDBC Driver Minor Version : " + dbMetaData.getDriverMinorVersion());
logger.info("=============");
}
..getters, setters
}

When i execute this line in setUp() block

Mockito.when(dataSource.getConnection()).thenReturn(Mockito.any(Connection.class));

I got:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at pl.sygnity.common.db.DataProviderTest.setUp(DataProviderTest.java:47)
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
But when I comment this out, it executes methods and throws NPE on loggerInfoAboutDatabase method..
java.lang.NullPointerException
at pl.test.common.db.DataProvider.loggerInfoAboutDatabase(DataProvider.java:186)
at pl.test.common.db.DataProvider.init(DataProvider.java:49)
at pl.test.common.db.DataProvider.getConnection(DataProvider.java:146)
at pl.test.common.db.DataProvider.parseSQLErrorDB(DataProvider.java:90)
at pl.test.common.db.DataProvider.parseSQLError(DataProvider.java:74)
at pl.test.common.db.DataProviderTest.parseSQLErrorUnconditionalTest(DataProviderTest.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at 

Any ideas here? Can I fake somehow this PoolDatasource and all related stuff?

答案1

得分: 1

我终于成功地进行了测试
基本上我正在模拟程序执行期间使用的每个嵌套对象

public class DataProviderTest {

    @InjectMocks
    DataProvider dataProvider;

    @Mock
    OracleConnection oracleConnection;

    @Mock
    DatabaseMetaData databaseMetadata;

    @Mock
    PoolDataSource dataSource;

    @Mock
    OracleCallableStatement oracleCallableStatement;

    @BeforeEach
    public void setUp() throws SQLException {
        MockitoAnnotations.initMocks(this);
        ReflectionTestUtils.setField(dataProvider, "parseSQLErrorFuntion", "您想要注入的字符串");
        Mockito.when(dataSource.getConnection()).thenReturn(oracleConnection);
        Mockito.when(oracleConnection.getMetaData()).thenReturn(databaseMetadata);
        Mockito.when(oracleConnection.prepareCall(Mockito.anyString())).thenReturn(oracleCallableStatement);
    }

    @Test
    public void parseSQLErrorUnconditionalTest() throws SQLException {
        String messageFromDB = "来自数据库的错误消息";
        String expected = messageFromDB;
        Mockito.when(oracleCallableStatement.getString(Mockito.anyInt())).thenReturn(messageFromDB);
        String actual = dataProvider.parseSQLError("未定义");
        Mockito.verify(oracleCallableStatement, Mockito.times(2)).execute();
        assertEquals(expected, actual);
    }
}
英文:

I finally managed to test it.
Basically I am mocking every nested objects that are used during program execution.

public class DataProviderTest {
@InjectMocks
DataProvider dataProvider;
@Mock
OracleConnection oracleConnection;
@Mock
DatabaseMetaData databaseMetadata;
@Mock
PoolDataSource dataSource;
@Mock
OracleCallableStatement oracleCallableStatement;
@BeforeEach
public void setUp() throws SQLException {
MockitoAnnotations.initMocks(this);
ReflectionTestUtils.setField(dataProvider, "parseSQLErrorFuntion", "String you want to inject");
Mockito.when(dataSource.getConnection()).thenReturn(oracleConnection);
Mockito.when(oracleConnection.getMetaData()).thenReturn(databaseMetadata);
Mockito.when(oracleConnection.prepareCall(Mockito.anyString())).thenReturn(oracleCallableStatement);
}
@Test
public void parseSQLErrorUnconditionalTest() throws SQLException {
String messageFromDB = "Error message from database";
String expected = messageFromDB;
Mockito.when(oracleCallableStatement.getString(Mockito.anyInt())).thenReturn(messageFromDB);
String actual = dataProvider.parseSQLError("Undefined");
Mockito.verify(oracleCallableStatement, Mockito.times(2)).execute();
assertEquals(expected, actual);
}
}

huangapple
  • 本文由 发表于 2020年9月24日 19:36:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/64045597.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定