2017-02-21 14 views
0

Я работаю на крошечном framework завернуть базы данных вызовов хранимых процедур по имени spwrapинтерфейсы Mocking JDBC в Спока

Here's the code:

@ConfineMetaClassChanges([CallableStatement]) 
def "Result of output parameter getInt throws SQLException"(){ 

    given: 
     def sqlExceptionMsg = "exception happend while tring to call getInt" 
     CallableStatement.metaClass.getObject = { int parameterIndex -> throw new SQLException(sqlExceptionMsg)} 

    when: 
     def custId = customerDao.createCustomer("Abdullah", "Mohammad") 

    then: 
     def e = thrown(CallException) 
     e.cause == SQLException 
     e.cause.message == sqlExceptionMsg 
} 

метод createCustomer не возвращает ссылку на CallableStatement, однако под капотом CallableStatement.getObject(int), и я хочу проверить случай, когда бросается SQLException.

Я пытаюсь переопределить bahvaiour на CallableStatement.getObject(int) класса (так как я должен ссылаться на используемый объект в рамках - по крайней мере, в этом сценарии)

выше тест не пройден, как это кажется CallableStatement.getObject(int) не является меняется. Однако, когда я использую <<, он жалуется (и должен). Как это сделать?

UPDATE:

Использование GroovyMock не помогает:

// test fails! 
def "Calling interface methods calling JDBC Driver methods"(){ 
    given: 
     CustomerDAO customerDAO2 = new DAO.Builder("jdbc:hsqldb:mem:customers", "sa", "").build().create(CustomerDAO); 
     def callableStatement = GroovyMock(JDBCCallableStatement, global: true) 
    when: 
     customerDAO2.createCustomer("Abdullah", "Mohammad") 
    then: 
     1 * callableStatement.getObject(_ as Integer) 
} 

Могу ли я добиться этого с другой оскорбляющей рамкой?

+0

Поскольку я не совсем знаком с классными метаклассами, у меня возникает вопрос: влияет ли изменение метакласса интерфейса на все реализации этого интерфейса? Потому что, если это не так (и я этого ожидаю, учитывая ограничения на прокси-сервер Java), тогда код в этом вопросе ничего не делает для реализации jdbc-драйвера 'CallableStatement'. –

+0

Есть ли у вас какая-то конкретная причина не использовать обычные макеты или заглушки, кроме как играть в мета-классы? – kriegaex

+0

Нет, но я думаю, что mocks работает с конкретным экземпляром класса, но это не мой случай. –

ответ

0

По моему опыту Спок не очень эффективен, когда дело доходит до Mocking статического/окончательного кода Java. Один из обходных решений, которые я предпринял для этого, заключается в том, чтобы помещать любые вызовы такого метода в свой собственный метод, к которому у Спока не должно возникнуть проблем с подключением.

public class MyClass { 
    //... stuff ... 

    protected Object retrieveObject(int) throws SQLException { 
     return CallableStatement.getObject(int) 
    } 
} 

public class MyClassTest extends Specification { 
def "Test example for wrapping unmockable method"(){ 
    given: 
     MyClass example = new MyClass(); 
    when: 
     example.callMethod("Parameters") 
    then: 
     1 * example.retrieveObject(_) >> { throw new SQLException(sqlExceptionMsg) } 
} 
} 
Смежные вопросы