Junit测试私有方法
https://my.oschina.net/u/2474629/blog/530373
下面是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构建方式。