ich mit einer Oracle 10g-Datenbank zu tun habe und die folgende gespeicherte Prozedur vorgesehen:Mock Oracle CallableStatement.getCursor()
procedure get_synopsis (
p_id in my_schema.products.p_id%type,
p_synopses out sys_refcursor); -- cursor of - synopsis_type, synopsis_text
In meinem Java-Code bereite ich die Anweisung auf diese Weise:
String idForDb = fromIdUrlToIdDb(prodIdUrl);
statement.registerOutParameter(1, OracleTypes.VARCHAR);
statement.setString(1, idForDb);
statement.registerOutParameter(2, OracleTypes.CURSOR);
Und ich bekomme die Daten, die ich auf diese Weise brauchen:
String defaultSyn, nonDefSyn;
String returnedId = ((OracleCallableStatement)stm).getString(1);
try (ResultSet synopses = ((OracleCallableStatement)stm).getCursor(2)){ // p_synopses - cursor of: synopsis_type, synopsis_text
while(synopses!=null && synopses.next()){
String type = synopses.getString(1) != null ? synopses.getString(1).toUpperCase() : null;
if(type != null){
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(synopses.getClob(2).getCharacterStream());
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
if("DEFAULT".equals(type)){
defaultSyn = sb.toString();
}else if("NONDEFAULT".equals(type)){
nonDefSyn = sb.toString();
}
// ...
}
}
}
in meinem Test s Wie kann ich spotten (OracleCallableStatement) stm.getCursor (2)?
Ich bin mit org.jmock.Mockery versucht, aber ohne Erfolg:
Mockery mockery_inner = new Mockery();
final ResultSet mocked_resultset = mockery_inner.mock(ResultSet.class);
mockery_inner.checking(new Expectations() {{
allowing(mocked_resultset).getString(1); will(returnValue("TEST_SYNOPSES-TYPE"));
allowing(mocked_resultset).getClob(2); will(returnValue("TEST_CLOooooooB"));
}});
Mockery mockery = new Mockery();
final CallableStatement statement = mockery.mock(CallableStatement.class);
mockery.checking(new Expectations() {{
allowing(statement).getString(1); will(returnValue("TEST_RETURNED-PROD-ID"));
allowing(statement).getCursor(2); will(returnValue(mocked_resultset)); // cannot find symbol getCursor(int). Location: interface java.sql.CallableStatement
}});
Grund klar ist: kann nicht Symbol GetCursor (int) finden. Ort: Schnittstelle java.sql.CallableStatement.
Wenn ich versuche, erlaubt ((OracleCallableStatement) statement) .getCursor (2) ich "java.lang.ClassCastException. Com.sun.proxy $ Proxy6 kann nicht auf oracle.jdbc.driver.OracleCallableStatement gegossen werden" . Hinweis: OracleCallableStatement ist keine Schnittstelle und kann daher nicht mit Mockerware verspottet werden.
Ich versuche, eine "manuelle" mock zu verwenden, aber ich habe Probleme, eine Instanz zu schaffen ..
class MockOracleCallableStatement implements OracleCallableStatement {
ResultSet mocked_resultset;
public MockOracleCallableStatement(){
Mockery mockery_inner = new Mockery();
mocked_resultset = mockery_inner.mock(ResultSet.class);
mockery_inner.checking(new Expectations() {{
allowing(mocked_resultset).getString(1); will(returnValue("DEFAULT")); // will pick value from an array
allowing(mocked_resultset).getClob(2); will(returnValue("TEST_CLOooooooooooB"));
}});
}
@Override
ResultSet getCursor(int paramIndex) throws SQLException{
return mocked_resultset;
}
@Override
String getString(int paramIndex) throws SQLException{
return "mockedGetString1--test";
}
}
Wir haben bereits Integrationstests an seinem Platz.Ich brauche diesen Komponententest nur, um zu testen, ob die Antwort korrekt in den erwarteten JSON serialisiert ist. Könnte wahrscheinlich mit etwas Refactoring diese Funktionalitäten dann trennen. Danke –
@Ga Sacchi Wenn Sie eine 100% -Testabdeckung anstreben, könnte es schwierig sein, dieses Ziel zu erreichen. Allerdings stimmte ich zu, dass Ihr spezielles Problem wahrscheinlich durch zu viel Logik in der Datenzugriffsebene verursacht wird. Sie könnten eine separate Klasse erstellen und nur das Ergebnisobjekt "Synopsen" vortäuschen. – RZet
Lassen Sie in diesem Fall Ihre Datenzugriffsebene ein Objekt zurückgeben, das Sie besitzen und kontrollieren, und führen Sie Ihre Integrationstests dagegen aus. Sie können dann separat testen, ob die Json-Konvertierung von diesem Objekt korrekt ausgeführt wird. – tddmonkey