1

我有一个通用类,它维护一个内部数组(比如数据)和数组中的元素数量(比如 N)(都是私有的)。我可以向数组添加元素,这将更新 N 的值。该类没有获取数据数组或 N 的方法。我仍然想编写单元测试来检查数组和 N 的状态。

    public class InternalArray<T> {
    private T[] data;
    private int N;
    private int head;
    public InternalArray() {
        super();
        data = (T[]) new Object[10];
        N = 0;
        head = 0;
    }

    public void add(T item){
        data[head]=item;
        head++;
        N++;
    }

    public T get(){
        T item = data[--head];
        N--;
        return item;
    }
}

在这里,我只能测试公共 API。但我需要测试私有变量的内部状态。我以为我可以使用反射访问字段。我尝试了下面的代码,我可以得到 N 的值。当涉及到 T[] 数据时,我不知道如何将结果转换ObjectString[](来自电话arrayf.get(inst)

public static void demoReflect(){
        try {           
                Class t = Class.forName("InternalArray");
                System.out.println("got class="+t.getName());
                InternalArray<String> inst = (InternalArray<String>) t.newInstance();
                System.out.println("got instance="+inst.toString());

                inst.add("A");
                inst.add("B");
                Field arrayf = t.getDeclaredField("data");
                arrayf.setAccessible(true);
                Field nf = t.getDeclaredField("N");
                nf.setAccessible(true);
                System.out.println("got arrayfield="+arrayf.getName());
                System.out.println("got int field="+nf.getName());
                int nval = nf.getInt(inst);
                System.out.println("value of N="+nval);
                Object exp = arrayf.get(inst);
                //how to convert this to String[] to compare if this is {"A","B"}

        } catch (ClassNotFoundException e) {            
            e.printStackTrace();
        } catch (InstantiationException e) {            
            e.printStackTrace();
        } catch (IllegalAccessException e) {            
            e.printStackTrace();
        } catch (SecurityException e) {         
            e.printStackTrace();
        } 
        catch (IllegalArgumentException e) {            
            e.printStackTrace();
        } catch (NoSuchFieldException e) {          
            e.printStackTrace();
        }
    }

这给出了下面的输出

got class=InternalArray
got instance=InternalArray@c2ea3f
got arrayfield=data
got int field=N
value of N=2
4

1 回答 1

2

Object你从调用中得到的是arrayf.get(inst)类型Object[],而不是类型String[],因为 Java 泛型是通过类型擦除实现的。你可以这样做:

Object[] strings = (Object[])arrayf.get(inst);
System.out.println(strings.length);
for (int i = 0 ; i != strings.length ; i++) {
    String s = (String)strings[i];
    ...
}

PS 我将远离关于对实现的私有细节进行单元测试是否是个好主意的讨论。

于 2013-09-13T15:25:20.883 回答