1

I have a generic class which maintains an internal array(say data) and number of elements(say N) in the array (both private).I can add elements to the array ,which will update the value of N.The public API of the class doesn't have get methods for the data array or N.Still I would like to write unit tests for checking the state of array and 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;
    }
}

Here, all I can test are the public APIs .. But I need to test the internal state of the private variables . I thought I would be able to access the fields using reflection.I tried the below code, I can get the value of N. When it comes to T[] data ,I can't figure out how to convert the resulting Object to a String[] ( from call 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();
        }
    }

This gave the output below

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

1 Answer 1

2

The Object that you get from the call of arrayf.get(inst) is of type Object[], not String[], because Java generics are implemented through type erasure. You can do this:

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

P.S. I am going to stay away from the discussion on whether it's a good idea to unit test the private details of the implementation.

Sign up to request clarification or add additional context in comments.

1 Comment

+1: A simple System.err.println( exp ); shows [Ljava.lang.Object;@693985fc: an array of objects

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.