2016-02-23 23 views
0

我有一個使用JDBC一些Groovy的一些2.4.x的代碼:Spocking的JDBC

class WidgetPersistor { 
    @Inject // Gets injected correctly by Guice, don't worry about it! 
    DataSource dataSource 

    Fizz getFizzByWidgetName(String name) { 
     Connection conn 
     PreparedStatement ps 
     ResultSet rs 

     try { 
      // JDBC code here 
     } catch(SQLException sqlExc) { 
      if(conn) { 
       try { 
        // NOTE: At the end of the day, I just want to verify 
        // that, given the 'name' arg to this method, the rollback 
        // doesn't fire! 
        conn.rollback() 
       } catch(SQLException rollBackExc) { 
        throw rollBackExc 
       } 
      } 
      throw sqlExc 
     } finally { 
      if(conn) { 
       try { 
        rs.close() 
        ps.close() 
        conn.close() 
       } catch(SQLException closingExc) { 
        throw closingExc 
       } 
      } 
     } 
    } 
} 

我想寫一個斯波克測試將執行此getFizzByWidgetName方法和驗證方法conn.rollback()從未執行 (這意味着我們從未嘗試回滾)。

這是我最好的嘗試:

def "getFizzByWidgetName succeeds without rollback"() { 
    given: "data client with db connections" 
    // Don't worry about how I get this for my test, but its a legit JDBC connection 
    DataSource ds = provideDataSource() 

    Connection mockConn = Mock(Connection) 
    PreparedStatement mockPS = Mock(PreparedStatement) 
    ResultSet mockRS = Mock(ResultSet) 

    mockPS.executeQuery() >> mockRS 
    mockConn.prepareStatement(_) >> mockPS 
    ds.connection >> mockConn // ??? Its like I want the DataSource half-mocked... 

    WidgetPersistor client = new WidgetPersistor(mockDS) 

    when: "we try to query something" 
    client.getFizzByWidgetName('fizzbuzz') 

    then: "we dont get any errors" 
    0 * mockConn.rollback() 
} 

任何想法,我要去哪裏出錯?

+2

是不是測試等效於測試'notThrown SQLException'? – dmahapatro

回答

1

如果您使用的是數據源來自一個真正的數據庫,並且在測試你的代碼寫在Groovy(看起來像的情況下),你可以使用元類來測試這樣的事情:

DataSource ds = provideDataSource() 

def connection = ds.connection 
connection.metaClass.rollback = { throw new AssertionError("rollback called") } 
ds.metaClass.connection = connection 

但它不是很漂亮。您應該可能調用您的方法而不使用模擬,並測試數據庫的狀態(即數據已提交,而不是回滾)