2012-04-12 82 views
1

我正在爲spring jdbc dao編寫單元測試。測試方法是:使用JMock寫一個簡單的春季JDBC單元測試DAO

public long getALong() { 
return simpleJdbcTemplate.queryForObject("sql query here", new RowMapper<Long>() { 
    public Long mapRow(ResultSet resultSet, int i) throws SQLException { 
    return resultSet.getLong("a_long"); 
    } 
}); 

}

以下是我在測試:

public void testGetALong() throws Exception { 
    final Long result = 1000L; 
    context.checking(new Expectations() {{ 
     oneOf(simpleJdbcTemplate).queryForObject("sql_query", new RowMapper<Long>() { 
     public Long mapRow(ResultSet resultSet, int i) throws SQLException { 
      return resultSet.getLong("a_long"); 
     } 
     }); 
     will(returnValue(result)); 
    }}); 
    Long seq = dao.getALong(); 
    context.assertIsSatisfied(); 
    assertEquals(seq, result); 
    } 

當然,測試不工作(否則,我也不會在這裏問這個問題)。問題是測試中的行映射器與DAO中的行映射器不同。所以期望沒有得到滿足。

我試圖把with圍繞sql查詢和with(any(RowMapper.class))爲row​​mapper。它也行不通,抱怨「並非所有參數都有明確的匹配器:要麼所有參數必須由匹配器指定,要麼全部必須由值指定,不能混合匹配器和值」

+1

請看Poutsma自己的Github的RowMapper測試用法:https://github.com/SpringSource/spring-framework/blob/3.1.x/org.springframework.jdbc/src/test/java/org /springframework/jdbc/core/RowMapperTests.java – 2012-04-12 17:03:04

回答

2

爲查詢提供一個匹配器字符串,例如

oneOf(simpleJdbcTemplate).queryForObject(
     with(equal("sql_query")), 
     with(any(RowMapper.class)) 
); 
+0

不行,它也不起作用。我得到了「並非所有參數都有明確的匹配器:要麼所有參數都必須由匹配器指定,要麼所有參數都必須由值指定,您不能混合匹配器和值」錯誤。 – Quincy 2012-04-12 17:22:15

+0

@Quincy,''''在'sql_query'之後失蹤。 – 2012-04-12 17:26:14

+0

我加了),然後我跑了。 – Quincy 2012-04-12 17:51:23

1

我在最後加入with(any(Object.class))解決了這個問題。

oneOf(jdbcTemplate).queryForObject(with(equal("sql_query")), with(any(RowMapper.class)), with(any(Object.class))); 

我覺得jmock找不到正確的方法來調用,因爲queryForObject方法得到了太多的重載。

+0

如果您告訴我們您正在測試的方法需要3個參數,而不是2個,那麼您會很高興。 – 2012-04-12 22:02:37

2

我想你可能會錯過這裏的幾點。你的第一次嘗試在模擬中再現了目標代碼的行爲。你真的想要測試什麼?

對於這種類型的測試,我更喜歡編寫一個集中測試來打擊真實的數據庫。多年前我試着嘲笑JDBC,並對此表示遺憾。這種代碼通常會失敗的是與數據庫的關係,而不是Java代碼本身。

這實際上是一個查詢(它不會改變對象之外的世界狀態),所以我傾向於使用allowing()子句而不是oneOf()。這是相同的基本機制,但更好地表達意圖。

最後,而不是直接調用context.assertIsSatisfied(),可以考慮使用

@RunWith(JMock.class) 

在測試的頂部。