首先先用eclipse建立一个一个Maven工程,然后在新建工程下添加一个Database类如下:
public class Database { private static final Logger log = LogManager.getLogger(); public static boolean createDatabase(String databaseName) { Connection con = DBCon.getConnection(); String sql = "create database "+databaseName; try { Statement statement = con.createStatement(); return statement.execute(sql); } catch (SQLException e) { e.printStackTrace(); log.error(e.getSQLState()+" "+e.getMessage()); return false; } } /** * 根据表名和参数的名字和属性创建表 * @param tableName 要创建表的名字 * @param cols 为Map类型其中Key是属性就是列名,Value是约束,就是数据类型,唯一性约束等 * @return */ public static boolean createTable(String tableName,Map<String,String> cols) { String createSQL = getSQL(tableName,cols); Connection con = DBCon.getConnection(); try { Statement statement = con.createStatement(); return statement.execute(createSQL); } catch (SQLException e) { e.printStackTrace(); log.error(e.getSQLState()+" "+e.getMessage()+"可能是SQL语句错误"); return false; } } /** * 根据表名和列名以及属性和约束创建表 * @param tableName 表名 * @param cols 列名属于 属性类型及约束 * @return 拼接的创建表的SQL字符串 */ private static String getSQL(String tableName,Map<String,String> cols) { StringBuffer sb = new StringBuffer(); sb.append("drop table if exist "); sb.append(tableName); sb.append(" create table "); sb.append(tableName); sb.append("("); for(Entry<String,String> entry:cols.entrySet()) { sb.append(entry.getKey()); sb.append(" "); sb.append(entry.getValue()); sb.append(","); } sb.replace(sb.lastIndexOf(","), sb.length(), ")"); return sb.toString(); } }
我们主要测试Database类的private static String getSQL(String tableName,Map<String,String> cols)方法。
我们在eclipse中选中Database文件右键选择new然后选择Junit Test Case然后入下图选择Junit 4 test,并且选择生成setUp()和tearDown()方法,setUp()主要是测试开始之前做一下初始化的工作,tearDown()主要是测试结束之后做一些清理工作。
单击next出现下面的对话框,因为我们的getSQL方法是一个私有的所以,eclipse并没有提供自动生成测试getSQL的方法。不过没有关系,我们直接单击finish然后在测试类中手动添加一个测试方法。
下面是Database的测试类,为了避免有一些包导入不一致,我把导入包的代码也贴出来了。
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class DatabaseTest { @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void testGetSQL() { String sql = "drop table if exist test create table test(id int unsigned primary key auto_increment,name varchar(50) not null unique)"; Map<String,String> cols = new HashMap<String,String>(); cols.put("id", "int unsigned primary key auto_increment"); cols.put("name", "varchar(50) not null unique"); String result = ""; Class<?> clazz = Database.class; try { Method getSQL = clazz.getDeclaredMethod("getSQL", String.class,Map.class); getSQL.setAccessible(true); result = (String) getSQL.invoke(new Database(), "test",cols); } catch (NoSuchMethodException e) { e.printStackTrace(); System.err.println(e.getMessage()+"方法没有找到"); } catch (SecurityException e) { e.printStackTrace(); System.out.println(e.getMessage()+"安全权限"); } catch (IllegalAccessException e) { e.printStackTrace(); System.err.println(e.getMessage()+"可能没有访问权限"); } catch (IllegalArgumentException e) { e.printStackTrace(); System.err.println(e.getMessage()+"可能有错误的参数"); } catch (InvocationTargetException e) { e.printStackTrace(); } System.out.println(sql); System.out.println(result); Assert.assertEquals(sql, result); } }
我们主要来看一看测试私有方法getSQL方法的testGetSQL。其中:
String sql = "drop table if exist test create table test(id int unsigned primary key auto_increment,name varchar(50) not null unique)";
是我们希望通过getSQL用tableName和map参数拼接出来的语句。
因为getSQL是私有方法,我们不能直接调用,所以我们必须通过反射来调用。
Class<?> clazz = Database.class; //活动Database的Class对象
通过Database的Class对象和方法名以及参数列表的Class对象取得一个Method对象。
Method getSQL = clazz.getDeclaredMethod("getSQL", String.class,Map.class);
下面这一条语句的作用是让getSQL这个Method对象所代表的私有方法能够在外部调用。
getSQL.setAccessible(true);
通过一个Database实例对象和参数来调用getSQL这个Method对象代表的方法。调用一个类方法肯定是要在一个实例上了,invoke的第一个参数就表示在哪一个实例上调用这个方法。
result = (String) getSQL.invoke(new Database(), "test",cols);
我们可以通过右键DatabaseTest文件选择Run As 选择Junit Test
好,没有问题。当然这是在我改过很多次之后,没有问题。每一次我只需要运行DatabaseTest就可以了,是不是节省了很多时间。
如果要用Maven来构建,需要在pom.xml中加入
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.3</version> </dependency> </dependencies>
然后在eclipse中选择项目右键选择Run As 选择Maven clean或者其他Maven构建方式。