How can I unit test a class that uses SimpleJdbcCall

I have a class that looks like this:

public class MyClass {

    private final SimpleJdbcCall simpleJdbcCall;

    public MyClass(final DataSource dataSource) {
        this(new JdbcTemplate(dataSource));
    }

    public MyClass(final JdbcTemplate template) {
        simpleJdbcCall = new SimpleJdbcCall(template)
            .withoutProcedureColumnMetaDataAccess()
            .withCatalogName("MY_ORACLE_PACKAGE")
            .withFunctionName("GET_VALUE")
            .withReturnValue()
            .declareParameters(
                new SqlOutParameter("RESULT", Types.VARCHAR))
            .declareParameters(
                new SqlParameter("P_VAR1_NAME", Types.VARCHAR))
            .declareParameters(
                new SqlParameter("P_VAR2_NAME", Types.VARCHAR))
            .useInParameterNames("P_VAR1_NAME", "P_VAR2_NAME");
    }

    private String getValue(final String input) {
        final SqlParameterSource params = new MapSqlParameterSource()
            .addValue("P_VAR1_NAME", input, Types.VARCHAR)
            .addValue("P_VAR2_NAME", null, Types.VARCHAR);
        return simpleJdbcCall.executeFunction(String.class, params);
    }
}

It works as expected, but I want to write a unit test for it, and it drives me crazy. I tried to taunt JdbcTemplate (Mockito), but this leads to mocking connections, metadata, etc., and I am lost in the time when called statement factories are included in the game.

I think I could write it so that SimpleJdbcCall is passed as a parameter to the new constructor and then mock it, but it seems hacky. I would prefer that the test does not affect the class if it does not improve it.

API SimpleJdbcCall. SQL , SQL Java, , 1000 . - ?

+5
5

, , SimpleJdbcCall.

MyClass(SimpleJdbcCall simpleJdbcCall) {
  this.simpleJdbcCall = simpleJdbcCall;
}

(, , , new).

"", Injection of Dependency. , , SimpleJdbcCall, .

new , .

Miško Hevery .

0

unit test it; , Oracle ( ).

SimpleJdbcCall, , , PowerMockito JMockit.

JMockit:

@Mocked DataSource ds;
@Mocked SimpleJdbcCall dbCall;

@Test
public void verifyDbCall() {
    String value = new MyClass(ds).getValue("some input");

    // assert on value

    new Verifications() {{
        SqlParameterSource params;
        dbCall.executeFunction(String.class, params = withCapture());
        // JUnit asserts on `params`
    }};
}
0

:

/*test*/ MyClass(final SimpleJdbcCall call) {
    simpleJdbcCall = call
        .withoutProcedureColumnMetaDataAccess()
        .withCatalogName("MY_ORACLE_PACKAGE")
        .withFunctionName("GET_VALUE")
        .withReturnValue()
        .declareParameters(
            new SqlOutParameter("RESULT", Types.VARCHAR))
        .declareParameters(
            new SqlParameter("P_VAR1_NAME", Types.VARCHAR))
        .declareParameters(
            new SqlParameter("P_VAR2_NAME", Types.VARCHAR))
        .useInParameterNames("P_VAR1_NAME", "P_VAR2_NAME");
}

, (= ) . , executeFunction() . .

, ; "POJO", .

, - .

SimpleJdbcCallOperations, , .

: JDBC. , , , , ,...

. ( , ).

JDBC, . , JDBC - . , .

:

0

I did this using http://www.jmock.org/

XML configuration -             

<bean id="simpleJDBCCall" class="org.springframework.jdbc.core.simple.SimpleJdbcCall">
    <property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>

Java file -

@Autowired
private SimpleJdbcCall jdbcCall;

Testing Class -

simpleJDBCCall = mockingContext.mock(SimpleJdbcCall.class);
mockingContext.checking(new Expectations() {
        { 
            oneOf(simpleJDBCCall).withSchemaName("test");
            will(returnValue(simpleJDBCCall));
            oneOf(simpleJDBCCall).withCatalogName("test");
            will(returnValue(simpleJDBCCall));
            oneOf(simpleJDBCCall).withProcedureName(ProcedureNames.TEST);
            will(returnValue(simpleJDBCCall));
            oneOf(simpleJDBCCall).execute(5);
            will(returnValue(testMap));
        }
0
source

I also prefer not to embed 15 different SimpleJdbcCalls in my repository, so I bite the bullet and add this to my test setup method:

DatabaseMetaData metaData = mock(DatabaseMetaData.class);
Connection con = mock(Connection.class);
when(con.getMetaData()).thenReturn(metaData);
DataSource ds = mock(DataSource.class);
when(ds.getConnection()).thenReturn(con);
jdbcTemplate = mock(JdbcTemplate.class);
when(jdbcTemplate.getDataSource()).thenReturn(ds);
0
source

Source: https://habr.com/ru/post/1612335/


All Articles