Java 在spock中模拟Jdbc接口

Java 在spock中模拟Jdbc接口,java,jdbc,mockito,spock,powermock,Java,Jdbc,Mockito,Spock,Powermock,我正在开发一个名为 : 该方法不返回对CallableStatement的引用,但是在后台调用了CallableStatement.getObject(int),我想测试抛出SQLException的情况 我试图覆盖CallableStatement.getObject(int)类上的bahvaiur(因为我必须通过框架引用所使用的对象-至少在这种情况下是这样) 上述测试失败,因为似乎没有更改CallableStatement.getObject(int)。然而,根据我的经验,当我使用时,Spo

我正在开发一个名为

:

该方法不返回对
CallableStatement
的引用,但是在后台调用了
CallableStatement.getObject(int)
,我想测试抛出
SQLException
的情况

我试图覆盖
CallableStatement.getObject(int)
类上的bahvaiur(因为我必须通过框架引用所使用的对象-至少在这种情况下是这样)


上述测试失败,因为似乎没有更改
CallableStatement.getObject(int)
。然而,根据我的经验,当我使用
时,Spock在模拟静态/最终Java代码方面并不是很强大。我所采取的解决方法之一是将任何此类方法调用放在它们自己的方法中,Spock应该不会有任何问题

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) }
}
}

因为我不完全熟悉groovy元类,所以我有一个问题:更改接口的元类是否会影响该接口的所有实现?因为如果不是(我也希望是这样,因为Java代理约束),那么这个问题中的代码对
CallableStatement
的实际jdbc驱动程序实现没有任何影响。您有什么具体的原因不使用普通的mock或stub,而是摆弄元类吗?没有,但我认为mocks可以处理类的特定实例,但这不是我的情况。
// 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)
}
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) }
}
}