unit testing private methods

Discussion in 'Java' started by jimgardener, Aug 13, 2008.

  1. jimgardener

    jimgardener Guest

    hi
    i am trying out PrivilegedAccessor class (of http://sourceforge.net/projects/privaccessor/)
    along with junit to test some private methods that process double[]
    [] .I think this uses reflection to access private methods


    public class MyClass {
    private double[] processArray(double[] inarray){
    double[] ret=new double[inarray.length];
    for(int i=0;i<inarray.length;i++){
    ret=inarray+100.0;
    }
    return ret;
    }
    }

    here is the testcase class
    <code>
    import junit.framework.TestCase;
    import junit.extensions.PrivilegedAccessor;

    public class MyClassTest extends TestCase{
    public MyClassTest(String name){
    super(name);
    }
    public void testMyClass()throws Exception{
    MyClass mc=new MyClass();
    assertNotNull(mc);

    double[] inputarray=new double[]{1.1,2.2,3.3,4.4};
    double[] ans=new double[]{101.1,102.2,103.3,104.4};
    double[] outputarray=(double[])
    (PrivilegedAccessor.invokeMethod(mc,"processArray(double[])",inputarray));
    assertEquals(outputarray,ans);

    }
    }

    <code>

    when i run the test ,i get an error message like

    java.lang.NoSuchMethodException: Method 'processArray(double[])'s
    parameter nr1 (double[]) not found

    This error originates at the call PrivilegedAccessor.invokeMethod(..)
    can someone tell me why this happens?

    thanks
    jim
     
    jimgardener, Aug 13, 2008
    #1
    1. Advertising

  2. jimgardener wrote:

    > hi
    > i am trying out PrivilegedAccessor class (of
    > http://sourceforge.net/projects/privaccessor/) along with junit to test
    > some private methods that process double[]
    > [] .I think this uses reflection to access private methods
    >
    >
    > public class MyClass {
    > private double[] processArray(double[] inarray){
    > double[] ret=new double[inarray.length];
    > for(int i=0;i<inarray.length;i++){
    > ret=inarray+100.0;
    > }
    > return ret;
    > }
    > }
    >
    > here is the testcase class
    > <code>
    > double[] outputarray=(double[])
    > (PrivilegedAccessor.invokeMethod(mc,"processArray(double[])",inputarray));
    > assertEquals(outputarray,ans);
    > <code>
    >
    > when i run the test ,i get an error message like
    >
    > java.lang.NoSuchMethodException: Method 'processArray(double[])'s
    > parameter nr1 (double[]) not found
    >
    > This error originates at the call PrivilegedAccessor.invokeMethod(..)
    > can someone tell me why this happens?


    Looking at the source code, it looks like PrivilegedAccessor cannot handle
    arrays.
    When I run your example, it breaks because it cannot find a class by the
    name of "double[]" (yes, the "[]" is part of the wanted class name).

    So you probably have two choices now:
    change your method signature or
    fix PrivilegedAccessor :)
     
    Andreas Kutschera, Aug 13, 2008
    #2
    1. Advertising

  3. jimgardener

    Simon Guest

    > (PrivilegedAccessor.invokeMethod(mc,"processArray(double[])",inputarray));

    I can only guess, but if PriviledgedAccessor tries something like
    Class.forName("double[]") it is not surprising that it fails. The correct string
    for the array class in this case would be "[D". For Objects, the array class can
    be obtained by using "[Lpackage.name.ClassName;".

    Hope this helps,
    Simon
     
    Simon, Aug 13, 2008
    #3
  4. jimgardener

    Daniel Pitts Guest

    jimgardener wrote:
    > hi
    > i am trying out PrivilegedAccessor class (of http://sourceforge.net/projects/privaccessor/)
    > along with junit to test some private methods that process double[]
    > [] .I think this uses reflection to access private methods
    >
    >
    > public class MyClass {
    > private double[] processArray(double[] inarray){
    > double[] ret=new double[inarray.length];
    > for(int i=0;i<inarray.length;i++){
    > ret=inarray+100.0;
    > }
    > return ret;
    > }
    > }
    >
    > here is the testcase class
    > <code>
    > import junit.framework.TestCase;
    > import junit.extensions.PrivilegedAccessor;
    >
    > public class MyClassTest extends TestCase{
    > public MyClassTest(String name){
    > super(name);
    > }
    > public void testMyClass()throws Exception{
    > MyClass mc=new MyClass();
    > assertNotNull(mc);
    >
    > double[] inputarray=new double[]{1.1,2.2,3.3,4.4};
    > double[] ans=new double[]{101.1,102.2,103.3,104.4};
    > double[] outputarray=(double[])
    > (PrivilegedAccessor.invokeMethod(mc,"processArray(double[])",inputarray));
    > assertEquals(outputarray,ans);
    >
    > }
    > }
    >
    > <code>
    >
    > when i run the test ,i get an error message like
    >
    > java.lang.NoSuchMethodException: Method 'processArray(double[])'s
    > parameter nr1 (double[]) not found
    >
    > This error originates at the call PrivilegedAccessor.invokeMethod(..)
    > can someone tell me why this happens?
    >
    > thanks
    > jim

    Unit tests are better off testing public interfaces only. Private
    implementation details shouldn't break the test unless they break client
    code. They also shouldn't break client code unless they break the test.

    Now, if the private method is an implementation of a particular
    algorithm that is used in several parts of the same class, you might
    consider pulling it out into its own class, making the method public,
    and unit testing *that* class. This gives you two benefits: The user of
    your class can provide you with a different implementation of that
    algorithm if they choose, and any other part of your system that needs
    to use that algorithm has access to the new class.

    Hope this helps,
    Daniel.
    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
     
    Daniel Pitts, Aug 13, 2008
    #4
  5. jimgardener

    Lew Guest

    On Aug 13, 4:00 am, jimgardener <> wrote:
    > hi
    > i am trying out PrivilegedAccessor class (of  http://sourceforge.net/projects/privaccessor/)
    > along with junit to test some private methods that process double[]
    > [] .I think this uses reflection to access private methods
    >
    > public class MyClass {
    >     private double[] processArray(double[] inarray){
    >         double[] ret=new double[inarray.length];
    >         for(int i=0;i<inarray.length;i++){
    >                 ret=inarray+100.0;
    >         }
    >         return ret;
    >     }
    >
    > }
    >
    > here is the testcase class
    > <code>
    > import junit.framework.TestCase;
    > import junit.extensions.PrivilegedAccessor;
    >
    > public class MyClassTest extends TestCase{
    >         public MyClassTest(String name){
    >                 super(name);
    >         }
    >         public void testMyClass()throws Exception{
    >                 MyClass mc=new MyClass();
    >                 assertNotNull(mc);
    >
    >                 double[] inputarray=new double[]{1.1,2.2,3.3,4.4};
    >                 double[] ans=new double[]{101.1,102.2,103.3,104.4};
    >                 double[] outputarray=(double[])
    > (PrivilegedAccessor.invokeMethod(mc,"processArray(double[])",inputarray));
    >                 assertEquals(outputarray,ans);
    >
    >        }
    >
    > }
    >
    > <code>
    >
    > when i run the test ,i get an error message like
    >
    > java.lang.NoSuchMethodException: Method 'processArray(double[])'s
    > parameter nr1 (double[]) not found
    >
    > This error originates at the call PrivilegedAccessor.invokeMethod(..)
    > can someone tell me why this happens?


    Private methods are amenable to proving via assertions. It is not
    usual to unit-test private methods, at least not with mechanisms
    (reflection) that are more bug-prone than the code under test.
    Private methods, being under total control of their owning class,
    depend on and establish program invariants. Put assertions at the
    invariant points to prove them. This would render all that
    complicated reflection fooferol unnecessary for unit-test purposes.

    It is still valid, of course, to use reflection in order to learn how
    to use reflection, but its use in production code should be limited to
    those use cases where it helps more than it hurts. I particularly
    recommend against unit-test code that introduces dependencies (other
    than on the unit-test framework itself) that do not exist in the code
    under test.

    --
    Lew
     
    Lew, Aug 13, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Maclean
    Replies:
    1
    Views:
    356
    Martin P. Hellwig
    Apr 13, 2010
  2. Ulrich Eckhardt

    unit-profiling, similar to unit-testing

    Ulrich Eckhardt, Nov 16, 2011, in forum: Python
    Replies:
    6
    Views:
    348
    Roy Smith
    Nov 18, 2011
  3. Marcus Lindemann
    Replies:
    2
    Views:
    94
    Derek Chesterfield
    Oct 27, 2005
  4. Bill Mosteller
    Replies:
    0
    Views:
    237
    Bill Mosteller
    Oct 22, 2009
  5. Avi
    Replies:
    0
    Views:
    504
Loading...

Share This Page