软件测试中出现私有方法时,需要使用反射机制来实现代码的测试。
首先,简略说一下反射是什么~~https://www.cnblogs.com/zhaoguhong/p/6937364.html
COPY——JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
其次,代码~~
被测试类:
public class MSD {
private static final int BITS_PER_BYTE = 8;
private static final int BITS_PER_INT = 32; // each Java int is 32 bits
private static final int R = 256; // extended ASCII alphabet size
private static final int CUTOFF = 15; // cutoff to insertion sort
// do not instantiate
private MSD() { }
//private MSD(int a) { }
/**
* Rearranges the array of extended ASCII strings in ascending order.
*
* @param a the array to be sorted
*/
public static void sort(String[] a) {
int n = a.length;
String[] aux = new String[n];
sort(a, 0, n-1, 0, aux);
}
// return dth character of s, -1 if d = length of string
private static int charAt(String s, int d) {
assert d >= 0 && d <= s.length();
if (d == s.length()) return -1;
return s.charAt(d);
}
// sort from a[lo] to a[hi], starting at the dth character
//sort(a, 0, n-1, 0, aux);
private static void sort(String[] a, int lo, int hi, int d, String[] aux) {
// cutoff to insertion sort for small subarrays
if (hi <= lo + CUTOFF) {
insertion(a, lo, hi, d);
return;
}
// compute frequency counts
int[] count = new int[R+2];
for (int i = lo; i <= hi; i++) {
int c = charAt(a[i], d);
count[c+2]++;
}
// transform counts to indicies
for (int r = 0; r < R+1; r++)
count[r+1] += count[r];
// distribute
for (int i = lo; i <= hi; i++) {
int c = charAt(a[i], d);
aux[count[c+1]++] = a[i];
}
// copy back
for (int i = lo; i <= hi; i++)
a[i] = aux[i - lo];
// recursively sort for each character (excludes sentinel -1)
for (int r = 0; r < R; r++)
sort(a, lo + count[r], lo + count[r+1] - 1, d+1, aux);
}
// insertion sort a[lo..hi], starting at dth character
private static void insertion(String[] a, int lo, int hi, int d) {
for (int i = lo; i <= hi; i++)
for (int j = i; j > lo && less(a[j], a[j-1], d); j--)
exch(a, j, j-1);
}
// exchange a[i] and a[j]
private static void exch(String[] a, int i, int j) {
String temp = a[i];
a[i] = a[j];
a[j] = temp;
}
// is v less than w, starting at character d
private static boolean less(String v, String w, int d) {
// assert v.substring(0, d).equals(w.substring(0, d));
for (int i = d; i < Math.min(v.length(), w.length()); i++) {
if (v.charAt(i) < w.charAt(i)) return true;
if (v.charAt(i) > w.charAt(i)) return false;
}
return v.length() < w.length();
}
/**
* Rearranges the array of 32-bit integers in ascending order.
* Currently assumes that the integers are nonnegative.
*
* @param a the array to be sorted
*/
public static void sort(int[] a) {
int n = a.length;
int[] aux = new int[n];
sort(a, 0, n-1, 0, aux);
}
// MSD sort from a[lo] to a[hi], starting at the dth byte
private static void sort(int[] a, int lo, int hi, int d, int[] aux) {
// cutoff to insertion sort for small subarrays
if (hi <= lo + CUTOFF) {
insertion(a, lo, hi, d);
return;
}
// compute frequency counts (need R = 256)
int[] count = new int[R+1];
int mask = R - 1; // 0xFF;
int shift = BITS_PER_INT - BITS_PER_BYTE*d - BITS_PER_BYTE;
for (int i = lo; i <= hi; i++) {
int c = (a[i] >> shift) & mask;
count[c + 1]++;
}
// transform counts to indicies
for (int r = 0; r < R; r++)
count[r+1] += count[r];
/************* BUGGGY CODE.
// for most significant byte, 0x80-0xFF comes before 0x00-0x7F
if (d == 0) {
int shift1 = count[R] - count[R/2];
int shift2 = count[R/2];
for (int r = 0; r < R/2; r++)
count[r] += shift1;
for (int r = R/2; r < R; r++)
count[r] -= shift2;
}
************************************/
// distribute
for (int i = lo; i <= hi; i++) {
int c = (a[i] >> shift) & mask;
aux[count[c]++] = a[i];
}
// copy back
for (int i = lo; i <= hi; i++)
a[i] = aux[i - lo];
// no more bits
if (d == 4) return;
// recursively sort for each character
if (count[0] > 0)
sort(a, lo, lo + count[0] - 1, d+1, aux);
for (int r = 0; r < R; r++)
if (count[r+1] > count[r])
sort(a, lo + count[r], lo + count[r+1] - 1, d+1, aux);
}
// TODO: insertion sort a[lo..hi], starting at dth character
private static void insertion(int[] a, int lo, int hi, int d) {
for (int i = lo; i <= hi; i++)
for (int j = i; j > lo && a[j] < a[j-1]; j--)
exch(a, j, j-1);
}
// exchange a[i] and a[j]
private static void exch(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
测试类:
public class MSDTest {
String[] a1 = {"a","c","b"};
String[] a2 = {"","b","c"};
String[] a3 = {"a","c","b","a","c","b","a","c","b","a","c","b","a","c","b","a","c","b"};
String[] a4 = {"avd","db","zc","radd","b","sascsa","a","b","c","a","b","c","a","b","c","a","b","c"};
String[] a5 = {"z","c","d","a","f","b","a","c","v","a","c","a","a","c","b","a","c","b"};
String[] a6 = {"zza","zcb"};
int[] b1 = {3,2,1};
int[] b2 = {1,2,3,4,5,2,4,5,6,22,1,12,2,222,22,4,7};
int[] b3 = {};
@Test
//私有的构造方法 私有的函数
public void testSortString() throws Exception {
// 得到Class
Class<MSD> class1 = MSD.class;
// 获取不带参数的构造方法
Constructor constructor=class1.getDeclaredConstructor();
//设置为可访问
constructor.setAccessible(true);
//创建实例
Object instance=(Object)constructor.newInstance();
Method method=class1.getDeclaredMethod("charAt", new Class[] {String.class,int.class});
//将方法设为可执行
method.setAccessible(true);
//反射机制调用方法的返回值是一个对象
Object result = method.invoke(instance, new Object[]{"",0});
assertEquals(-1, result);
Method method1=class1.getDeclaredMethod("sort", new Class[] {int[].class,int.class,int.class,int.class,int[].class});
//将方法设为可执行
method1.setAccessible(true);
//反射机制调用方法的返回值是一个对象
//method1.invoke(instance, new Object[]{b2,0,6,4,b3});
Object result1 = method1.invoke(instance, new Object[]{b2,0,10,4,b3});
MSD.sort(a1);
MSD.sort(a2);
MSD.sort(a3);
MSD.sort(a4);
MSD.sort(a5);
MSD.sort(a6);
MSD.sort(b1);
MSD.sort(b2);
}
@Test
public void testSortInt() {
String[] a = {"1"};
MSD.sort(a);
}
}
这个代码中,被测试类的构造方法是私有、无参的,里面被测试的方法也是私有的。
如果被测试方法不是私有的,testToString中部分代码可改为:
// 得到Class
Class clazz = Class.forName("net.mooctest.MSD");
// 获取带参数的构造方法
Constructor con = clazz.getDeclaredConstructor(int.class);
//设置为可访问
con.setAccessible(true);
MSD s = (MSD) con.newInstance(18);
//获取类中的带参方法(public方法)
Method method=clazz.getMethod("sort", int[].class);
//调用带参方法
method.invoke(s,b1);
如果构造方法不是私有时,可以这样写:
//获取类
Class clazz = Class.forName("net.mooctest.BPlusTree");
//获取带参数的类构造方法
Constructor con1 = clazz.getDeclaredConstructor(int.class);
Constructor con2 = clazz.getDeclaredConstructor(int.class,int.class);
//设置为可访问
con1.setAccessible(true);
con2.setAccessible(true);
//创建实例
//BPlusTree BP = (BPlusTree) con1.newInstance(3);
//获取方法
Method method = clazz.getDeclaredMethod("findLeaf", int.class);
//设置方法为可访问
method.setAccessible(true);
//反射机制中返回值是一个对象
//Object obj = method.invoke(bp1, 1);
Object obj2 = method.invoke(bp2, 1);
访问类的私有变量时,
class QuadTree{
private Node root_;
}
class Node{}
QuadTree quadTree0 = new QuadTree ();
Field field = quadTree0.getClass().getDeclaredField("root_");field.setAccessible(true);
Object obj = field.get(quadTree0);
Node node = (Node)obj;
来源:https://www.cnblogs.com/love528/p/9858971.html