软件测试——java反射机制

不问归期 提交于 2020-03-28 08:23:09

软件测试中出现私有方法时,需要使用反射机制来实现代码的测试。

首先,简略说一下反射是什么~~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;

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!