/src/tests/net/sf/persist/tests/framework/BeanTest.java
Java | 353 lines | 205 code | 70 blank | 78 comment | 26 complexity | 0fd7647d6ad347f7f5cd48b810a77462 MD5 | raw file
1 2// $Id$ 3 4package net.sf.persist.tests.framework; 5 6import static org.junit.Assert.assertEquals; 7import static org.junit.Assert.assertNotNull; 8import static org.junit.Assert.assertNull; 9import static org.junit.Assert.assertTrue; 10 11import java.sql.Connection; 12import java.sql.SQLException; 13import java.util.List; 14import java.util.Map; 15 16import net.sf.persist.Persist; 17import net.sf.persist.Result; 18import net.sf.persist.TableMapping; 19import net.sf.persist.tests.common.Simple; 20import net.sf.persist.tests.common.TestSimple; 21 22public class BeanTest { 23 24 // TODO: test updates passing a single value 25 26 public static void test(Persist persist, BeanMap beanMap) { 27 Connection connection = persist.getConnection(); 28 Class cls = DynamicBean.createBeanClass(beanMap, false); 29 Class clsNoTable = DynamicBean.createBeanClass(beanMap, true); 30 31 String tableName = dbName(beanMap.getClassName()); 32 33 try { 34 connection.createStatement().execute("delete from " + tableName); 35 } catch (SQLException e) { 36 throw new RuntimeException(e); 37 } 38 BeanTest.testAll(persist, cls, clsNoTable, beanMap); 39 40 41 try { 42 connection.createStatement().execute("delete from " + tableName); 43 } catch (SQLException e) { 44 throw new RuntimeException(e); 45 } 46 BeanTest.testAllNull(persist, cls, clsNoTable, beanMap); 47 48 if (beanMap.supportsAutoGeneratedKeys()) { 49 testExecuteUpdateAutoGeneratedKeys(persist); 50 testSetAutoGeneratedKeys(persist); 51 } 52 53 } 54 55 /** 56 * Perform tests using a bean with non-null values 57 */ 58 public static void testAll(Persist persist, Class cls, Class clsNoTable, BeanMap beanMap) { 59 persist.setAutoCommit(false); 60 Object obj = DynamicBean.createInstance(cls, beanMap, false); 61 BeanTest.testInsert(persist, obj, beanMap); 62 BeanTest.testSelectByFields(persist, obj, beanMap); 63 BeanTest.testSelectFields(persist, obj, beanMap, false); 64 BeanTest.testSelectMap(persist, obj, beanMap); 65 BeanTest.testReadNoTable(persist, obj, clsNoTable); 66 persist.commit(); 67 persist.setAutoCommit(true); 68 } 69 70 /** 71 * Perform tests using a bean with null values 72 */ 73 public static void testAllNull(Persist persist, Class cls, Class clsNoTable, BeanMap beanMap) { 74 persist.setAutoCommit(false); 75 Object objNull = DynamicBean.createInstance(cls, beanMap, true); 76 BeanTest.testInsert(persist, objNull, beanMap); 77 BeanTest.testSelectByFieldsNull(persist, objNull, beanMap); 78 BeanTest.testSelectFields(persist, objNull, beanMap, true); 79 BeanTest.testSelectMap(persist, objNull, beanMap); 80 BeanTest.testReadNoTable(persist, objNull, clsNoTable); 81 persist.commit(); 82 persist.setAutoCommit(true); 83 } 84 85 /** 86 * tests insertion of a bean 87 */ 88 public static void testInsert(Persist persist, Object obj, BeanMap beanMap) { 89 Class cls = obj.getClass(); 90 String tableName = dbName(obj.getClass().getSimpleName()); 91 92 // perform insert 93 persist.insert(obj); 94 95 // check if a single result exists in the table (expects the table to be clean by the beginning of the process) 96 String sql = "select * from " + tableName; 97 List read = persist.readList(cls, sql); 98 if (read.size()!=1) { 99 throw new AssertionError("Expected 1 result but got [" + read.size() + "] as result of sql [" + sql + "]"); 100 } 101 102 // check if the bean read is the same as inserted 103 if (!obj.equals(read.get(0))) { 104 throw new AssertionError("Expected [" + DynamicBean.toString(obj) + "] but got [" 105 + DynamicBean.toString(read.get(0)) + "] as result of [" + sql + "]"); 106 } 107 } 108 109 /** 110 * tests reading with NoTable class 111 */ 112 public static void testReadNoTable(Persist persist, Object obj, Class clsNoTable) { 113 114 String tableName = dbName(obj.getClass().getSimpleName()); 115 116 // now read with NoTable (assumes previously inserted data) 117 Object objNoTable = persist.read(clsNoTable, "select * from " + tableName); 118 119 // compare values 120 if (!DynamicBean.compareBeansFromDifferentClasses(obj, objNoTable)) { 121 throw new AssertionError("Expected [" + DynamicBean.toString(obj) + "] but got [" 122 + DynamicBean.toString(objNoTable) + "]"); 123 } 124 } 125 126 /** 127 * For each field and each field type, execute a query in the format 128 * select * from tableName where columnName=? 129 */ 130 public static void testSelectByFields(Persist persist, Object obj, BeanMap beanMap) { 131 Class cls = obj.getClass(); 132 String tableName = dbName(obj.getClass().getSimpleName()); 133 134 // for each field in the bean 135 for (FieldMap fieldMap : beanMap.getFields()) { 136 137 // only perform tests if the field supports queries by value (blobs in oracle, for instance, don't) 138 if (fieldMap.isSupportsQueryByValue()) { 139 String columnName = dbName(fieldMap.getFieldName()); 140 String sql = "select * from " + tableName + " where " + columnName + "=?"; 141 Object fieldValue = DynamicBean.getFieldValue(obj, fieldMap.getFieldName()); 142 143 // for each type supported by the field, test if a query using an object of that type returns data correctly 144 for (Class fieldType : fieldMap.getTypes()) { 145 146 // use value converted to the type being tested 147 Object fieldValueConverted = DynamicBean.convertToType(fieldType, fieldValue); 148 149 // query using the type being tested 150 Object ret = persist.read(cls, sql, fieldValueConverted); 151 152 // check if the result is not null and has the same data as the object being tested 153 if (ret==null) { 154 throw new AssertionError("Expected not null value but got null as result of [" + sql 155 + "] with parameter [" + fieldValue + "]"); 156 } 157 if (!obj.equals(ret)) { 158 throw new AssertionError("Expected [" + DynamicBean.toString(obj) + "] but got [" 159 + DynamicBean.toString(ret) + "] as result of [" + sql + "]"); 160 } 161 } 162 } 163 } 164 } 165 166 /** 167 * For each field, execute a query in the format 168 * select * from tableName where columnName is null 169 */ 170 public static void testSelectByFieldsNull(Persist persist, Object obj, BeanMap beanMap) { 171 Class cls = obj.getClass(); 172 String tableName = dbName(obj.getClass().getSimpleName()); 173 174 // for each field in the bean 175 for (FieldMap fieldMap : beanMap.getFields()) { 176 177 // only perform tests if the field supports queries by value (blobs in oracle, for instance, don't) 178 if (fieldMap.isSupportsQueryByValue()) { 179 String columnName = dbName(fieldMap.getFieldName()); 180 181 // test if query for null value in the column related with the field return the object correctly 182 String sql = "select * from " + tableName + " where " + columnName + " is null"; 183 Object ret = persist.read(cls, sql); 184 if (ret==null) throw new AssertionError("Expected not null value but got null as result of [" + sql + "]"); 185 if (!obj.equals(ret)) { 186 throw new AssertionError("Expected [" + DynamicBean.toString(obj) + "] but got [" 187 + DynamicBean.toString(ret) + "] as result of [" + sql + "]"); 188 } 189 } 190 } 191 } 192 193 /** 194 * for each field, and for each field type perform a query in the form 195 * select columnName from tableName 196 */ 197 public static void testSelectFields(Persist persist, Object obj, BeanMap beanMap, boolean useNulls) { 198 String tableName = dbName(obj.getClass().getSimpleName()); 199 200 // for each field in the bean 201 for (FieldMap fieldMap : beanMap.getFields()) { 202 String columnName = dbName(fieldMap.getFieldName()); 203 String sql = "select " + columnName + " from " + tableName; 204 205 // get field value from the bean 206 Object fieldValue = DynamicBean.getFieldValue(obj, fieldMap.getFieldName()); 207 208 // for each supported type 209 for (Class fieldType : fieldMap.getTypes()) { 210 211 // query for a single column data using the field type (eg byte, Byte, String, InputStream, etc.) 212 Object ret = persist.read(fieldType, sql); 213 214 if (useNulls) { 215 // check if "null", which means 0 for numeric values type as primitive (byte, short, int, etc.) 216 if (!DynamicBean.isNull(fieldType, ret)) throw new AssertionError("Expected null value but got [" + ret 217 + "] as result of [" + sql + "]"); 218 } 219 else { 220 if (ret==null) { 221 throw new AssertionError("Expected not null value but got null as result of [" + sql + "]"); 222 } 223 224 // TODO: maybe test compatibility of return type with field type? 225 226 // compare values using a method that takes into consideration "compatible" types 227 // (eg char[]-String, double-BigDecimal, etc) 228 Object retConverted = DynamicBean.convertToType(fieldValue.getClass(), ret); 229 if (!DynamicBean.compareValues(fieldValue, retConverted)) { 230 throw new AssertionError("Expected [" + fieldValue + "] but got [" + ret + "] as result of [" + sql + "]"); 231 } 232 } 233 } 234 } 235 } 236 237 /** 238 * perform [select * from tableName] and get the results as a map 239 */ 240 public static void testSelectMap(Persist persist, Object obj, BeanMap beanMap) { 241 String tableName = dbName(obj.getClass().getSimpleName()); 242 243 // read list of all data in the table as a map 244 String sql = "select * from " + tableName; 245 List<Map<String,Object>> mapList = persist.readMapList(sql); 246 247 // asserts there's only one entry (added during the insert test) 248 if (mapList.size()!=1) { 249 throw new AssertionError("Expected 1 result but got [" + mapList.size() + "] as result of sql [" + sql + "]"); 250 } 251 252 // use the first (or single) map returned 253 Map m = mapList.get(0); 254 255 // for each field in the bean 256 for (FieldMap fieldMap : beanMap.getFields()) { 257 String columnName = dbName(fieldMap.getFieldName()); 258 259 // get the field value 260 Object fieldValue = DynamicBean.getFieldValue(obj, fieldMap.getFieldName()); 261 262 // get the corresponding map value 263 Object mapValue = m.get(columnName); 264 265 // if field supports comparisons on the map values (mysql's year2 and year4, for instance, 266 // have Date objects here, but must be inserted as short's, therefore can't be compared properly) 267 if (fieldMap.isSupportsCompareMapValue()) { 268 269 // compare values using a method that takes into consideration "compatible" types 270 // (eg char[]-String, double-BigDecimal, etc) 271 if (!DynamicBean.compareValues(fieldValue, mapValue)) { 272 throw new AssertionError("Map entry [" + columnName + "]=[" + mapValue + "] does not match field [" 273 + fieldMap.getFieldName() + "]=[" + fieldValue + "] as result of sql [" + sql + "]"); 274 } 275 } 276 } 277 } 278 279 /** 280 * Tests if explicitly specifying autoGeneratedKeys in executeUpdate works 281 */ 282 public static void testExecuteUpdateAutoGeneratedKeys(Persist persist) { 283 284 TableMapping mapping = (TableMapping) persist.getMapping(Simple.class); 285 if (mapping.supportsGetGeneratedKeys()) { 286 287 // some data to insert 288 int intCol = DynamicBean.randomInt(0,Integer.MAX_VALUE/2); 289 String stringCol = DynamicBean.randomString(255); 290 291 // insert with explicit auto generated keys and check result object data 292 String[] autoGeneratedKeys = new String[] { "id" }; 293 Result result = persist.executeUpdate(Simple.class, "insert into simple (int_col,string_col) values(?,?)", 294 autoGeneratedKeys, intCol, stringCol); 295 assertEquals(1, result.getGeneratedKeys().size()); 296 assertEquals(1, result.getRowsModified()); 297 298 // read object and compare with inserted data 299 Simple simpleRead = persist.read(Simple.class, "select * from simple where int_col=? and string_col=?", 300 intCol, stringCol); 301 assertNotNull(simpleRead); 302 assertEquals(intCol, simpleRead.getIntCol()); 303 assertEquals(stringCol, simpleRead.getStringCol()); 304 305 // delete object and check it was removed 306 persist.delete(simpleRead); 307 simpleRead = persist.read(Simple.class, "select * from simple where int_col=? and string_col=?", intCol, stringCol); 308 assertNull(simpleRead); 309 } 310 311 } 312 313 /** 314 * Tests setUpdateGeneratedKeys 315 */ 316 public static void testSetAutoGeneratedKeys(Persist persist) { 317 318 TableMapping mapping = (TableMapping) persist.getMapping(Simple.class); 319 if (mapping.supportsGetGeneratedKeys()) { 320 321 persist.setUpdateAutoGeneratedKeys(true); 322 323 // insert object with setUpdateAutoGeneratedKeys option 324 Simple simpleInsert = TestSimple.buildSimple(); 325 simpleInsert.setId(0); 326 persist.insert(simpleInsert); 327 assertTrue(0!=simpleInsert.getId()); 328 329 // read object using primary key (auto generated) 330 Simple simpleRead = persist.read(Simple.class, "select * from simple where id=?", simpleInsert.getId()); 331 assertEquals(simpleInsert, simpleRead); 332 333 // delete object by primary key and check it was removed 334 persist.delete(simpleRead); 335 simpleRead = persist.readByPrimaryKey(Simple.class, simpleRead.getId()); 336 assertNull(simpleRead); 337 338 persist.setUpdateAutoGeneratedKeys(false); 339 340 } 341 } 342 343 // ---------- helpers ---------- 344 345 /** 346 * Returned the database table/column name related with a given bean/field name 347 */ 348 private static String dbName(String s) { 349 String name = s.replaceAll("([A-Z])", "_$1").toLowerCase(); 350 return name.charAt(0)=='_' ? name.substring(1) : name; 351 } 352 353}