How to cover private method if it uses only in field declaration?

How do I use JUnit to test a class that has internal private methods, fields or nested classes? It seems bad to change the access modifier for a method just to be able to run a test.

Replay

If you have somewhat of a legacy application, and you're not allowed to change the visibility of your methods, the best way to test private methods is to use reflection.

Internally we're using helpers to get/set private and private static variables as well as invoke private and private static methods. The following patterns will let you do pretty much anything related to the private methods and fields. Of course you can't change private static final variables through reflection.

Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

And for fields:

Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);


Notes:
1. targetClass.getDeclaredMethod(methodName, argClasses) lets you look into private methods. The same thing applies for getDeclaredField.
2. The setAccessible(true) is required to play around with privates.

The best way to test a private method is via another public method. If this cannot be done, then one of the following conditions is true:

  1. The private method is dead code
  2. There is a design smell near the class that you are testing
  3. The method that you are trying to test should not be private

When I have private methods in a class that is sufficiently complicated that I feel the need to test the private methods directly, that is a code smell: my class is too complicated.

My usual approach to addressing it is to tease out a new class that contains the interesting bits. Often, this method and the fields it interacts with, and maybe another method or two can be extracted in to a new class.

The new class exposes these methods as 'public', so they're accessible for unit testing. The new and old classes are now both simpler than the original class, which is great for me (I need to keep things simple, or I get lost!).

Note that I'm not suggesting that anyone create classes without using their brain! The point here is to use the forces of unit testing to help you find good new classes.

From this article: Testing Private Methods with JUnit and SuiteRunner (Bill Venners), you basically have 4 options:

  • Don't test private methods.
  • Give the methods package access.
  • Use a nested test class.
  • Use reflection.

I have used reflection to do this in the past, and in my opinion it was a big mistake.

Strictly speaking, you should not be writing unit tests that directly test private methods. What you should be testing is the public contract that the class has with other objects; you should never directly test an object's internals. If another developer wants to make a small internal change to the class, which doesn't affect the classes public contract, he/she then has to modify your reflection based test to ensure that it works. If you do this repeatedly throughout a project unit tests and then stop being a useful measurement of code health, and start to become a hindrance to development, and an annoyance to the development team.

What I recommend doing instead is using a code coverage tool such as Cobertura, to ensure that the unit tests you write provide decent coverage of the code in private methods. That way, you indirectly test what the private methods are doing, and maintain a higher level of agility.

Generally a unit test is intended to exercise the public interface of a class or unit. Therefore, private methods are implementation detail that you would not expect to test explicitly.

The private methods are called by a public method, so the inputs to your public methods should also test private methods that are called by those public methods. When a public method fails, then that could be a failure in the private method.

Just two examples of where I would want to test a private method:

  1. Decryption routines - I would not want to make them visible to anyone to see just for the sake of testing, else anyone can use them to decrypt. But they are intrinsic to the code, complicated, and need to always work. (the obvious exception is reflection which can be used to view even private methods in most cases, when SecurityManager is not configured to prevent this)
  2. Creating an SDK for community consumption. Here public takes on a wholly different meaning, since this is code that the whole world may see (not just internal to my app). I put code into private methods if I don't want the SDK users to see it - I don't see this as code smell, merely as how SDK programming works. But of course I still need to test my private methods, and they are where the functionality of my SDK actually lives.

I understand the idea of only testing the "contract". But I don't see one can advocate actually not testing code - ymmv.

So my tradeoff involves complicating the JUnits with reflection, rather than compromising my security & SDK.

To test legacy code with large and quirky classes, it is often very helpful to be able to test the one private (or public) method I'm writing right now.

I use the junitx.util.PrivateAccessor-package. Lots of helpful one-liners for accessing private methods and private fields.

import junitx.util.PrivateAccessor;

PrivateAccessor.setField(myObjectReference, "myCrucialButHardToReachPrivateField", myNewValue);
PrivateAccessor.invoke(myObjectReference, "privateMethodName", java.lang.Class[] parameterTypes, java.lang.Object[] args);

Hope that was helpful :)

EDIT: Having tried Cem Catikkas' solution using reflection, I'd have to say his was a more elegant solution than I have described here. However, if you're looking for an alternative to using reflection, and have access to the source you're testing, this will still be an option.

There is possible merit in testing private methods of a class, particularly with test driven development, where you would like to design small tests before you write any code.

Creating a test with access to private members and methods can test areas of code which are difficult to target specifically with access only to public methods. If a public method has several steps involved, it can consist of several private methods, which can then be tested individually.

Advantages:

  • can test to a finer granularity

Disadvantages:

  • test code must reside in the same file as source code, which can be more difficult to maintain
  • similarly with .class output files, they must remain within the same package as declared in source code

However, if continuous testing requires this method, it may be a signal that the private methods should be extracted, which could be tested in the traditional, public way.

Here is a convoluted example of how this would work:

// import statements and package declarations

public class ClassToTest
{
    private int decrement(int toDecrement) {
        toDecrement--;
        return toDecrement;
    }

    // constructor and rest of class

    public static class StaticInnerTest extends TestCase
    {
        public StaticInnerTest(){
            super();
        }

        public void testDecrement(){
            int number = 10;
            ClassToTest toTest= new ClassToTest();
            int decremented = toTest.decrement(number);
            assertEquals(9, decremented);
        }

        public static void main(String[] args) {
            junit.textui.TestRunner.run(StaticInnerTest.class);
        }

    }
}

Inner class would be compiled to ClassToTest$StaticInnerTest.

See also: http://www.javaworld.com/javaworld/javatips/jw-javatip106.html

If you're trying to test existing code that you're reluctant or unable to change, reflection is a good choice.

If the class's design is still flexible and you've got a complicated private method that you'd like to test separately, I suggest you pull it out into a separate class and test that class separately. This doesn't have to change the public interface of the original class, it can internally create an instance of the helper class and call the helper method.

If you want to test difficult error conditions coming from the helper method, you can go a step further. Extract an interface from the helper class, add a public getter and setter to the original class to inject the helper class (used through its interface), and then inject a mock version of the helper class into the original class to test how the original class responds to exceptions from the helper. This approach is also helpful if you want to test the original class without also testing the helper class.

As others have said... don't test private methods directly. Here are a few thoughts:

  1. keep all methods small and focused (easy to test, easy to find what is wrong)
  2. use code coverage tools, I like Cobertura (oh happy day, looks like a new version is out!)

Run the code coverage on the unit tests. If you see that methods are not fully tested add to the tests to get the coverage up. Aim for 100% code coverage but realize that you probably won't get it.

Since you're using JUnit, have you looked at junit-addons? It has the ability to ignore the java security model and access private methods and attributes.

If you want to test private methods of a legacy application where you can't change the code, one option is jMockit, which will allow you to create mocks to an object even when they're private to the class.

Testing private methods breaks the encapsulation of your class because every time you change the internal implementation you break client code (in this case, the tests).

So don't test private methods.

Private methods are consumed by public ones, otherwise, they're dead code. That's why you test the public method, asserting the expected results of the public method and thereby, the private methods it consumes.

Testing private methods should be tested by debugging before running your unit tests on public methods.

They may also be debugged using test driven development, debugging your unit tests until all your assertions are met.

I personally believe it is better to create classes using TDD; creating the public method stubs, then generating unit tests with all the assertions defined in advance, so the expected outcome of the method is determined before you code it. This way, you don't go down the wrong path of making the unit test assertions fit the results. Your class is then robust and meets requirements when all your unit tests pass.

As many above have suggested, a good way is to test them via your public interfaces.

If you do this, it's a good idea to use a code coverage tool (like Emma) to see if your private methods are in fact being executed from your tests.

If using Spring, ReflectionTestUtils provides some handy tools that help out here with minimal effort. For example, to set up a mock on a private member without being forced to add an undesirable public setter:

ReflectionTestUtils.setField(theClass, "theUnsettableField", theMockObject);

The answer from JUnit.org FAQ page:

But if you must...

If you are using JDK 1.3 or higher, you can use reflection to subvert the access control mechanism with the aid of the PrivilegedAccessor. For details on how to use it, read this article.

If you are using JDK 1.6 or higher and you annotate your tests with @Test, you can use Dp4j to inject reflection in your test methods. For details on how to use it, see this test script.

P.S. I'm the main contributor to Dp4j, ask me if you need help. :)

First, I'll throw this question out: why do your private members need isolated testing? Are they that complex, providing such complicated behaviors as to require testing apart from public surface? It's unit testing, not 'line-of-code' testing. Don't sweat the small stuff.

If they are that big, big enough that these private members are each a 'unit' large in complexity -- consider refactoring such private members out of this class.

If refactoring is inappropriate or infeasible, can you use the strategy pattern to replace access to these private member functions / member classes when under unit test? Under unit test, the strategy would provide added validation, but in release builds it would be simple pass-thru.

Wooww, takes some guts to add an answer here :)

Today, I pushed a library to help testing private methods and fields.It has been designed with Android in mind but can really be used for any Java project.

If you got some code with private methods or fields or constructors, you can use BoundBox. It does exactly what you are looking for. Here below is an example of a test that accesses 2 private fields of an Android activity to test it :

@UiThreadTest
public void testCompute() {
    // given
    boundBoxOfMainActivity = new BoundBoxOfMainActivity(getActivity());

    // when
    boundBoxOfMainActivity.boundBox_getButtonMain().performClick();

    // then
    assertEquals("42", boundBoxOfMainActivity.boundBox_getTextViewMain().getText());
}

BoundBox makes it easy to test private/protected fields, methods and constructors. You can even access stuff that is hidden by inheritance. Indeed, BoundBox breaks encapsulation. It will give you access to all that through reflection, BUT every thing is checked at compile time.

Ideal for testing some legacy code. Use it carefully. ;)

https://github.com/stephanenicolas/boundbox

here is my generic function to test private fields:

protected <F> F getPrivateField( String fieldName, Object obj)
    throws NoSuchFieldException, IllegalAccessException {
    Field field =
        obj.getClass().getDeclaredField( fieldName );

    field.setAccessible( true );
    return (F)field.get( obj );
}

A private method only be accessed within the same class. So there is no way to test a “private” method of a target class from any test class. A way out is that you can perform unit testing manually or can change your method from “private” to “protected”.

And then A protected method can only be accessed within the same package where the class is defined. So, testing a protected method of a target class means we need to define your test class in the same package as the target class.

if all the above is Not suits your requirement Use the reflection to access the private method

In Spring framework you can test private methods using method:

ReflectionTestUtils.invokeMethod()

for example:

ReflectionTestUtils.invokeMethod(TestClazz, "createTest", "input data");

I tend not to test private methods. There lies madness. Personally, I believe you should only test your publicly exposed interfaces (and that includes protected and internal methods).

I'd use reflection, since I don't like the idea of changing the access to a package on the declared method just for the sake of testing. However, I usually just test the public methods which should also ensure the the private methods are working correctly.

you can't use reflection to get private methods from outside the owner class, the private modifier affects reflection also

This is not true. You most certainly can, as mentioned in Cem Catikkas's answer.

In C# you could have used System.Reflection, though in Java I don't know. Though I feel the urge to answer this anyway since if you "feel you need to unit test private methods" my guess is that there is something else which is wrong...

I would seriously consider looking at my architecture again with fresh eyes....

I am not sure whether this is a good technique but I developed the following pattern to unit test private methods:

I don't modify the visibility of the method that I want to test and add an additional method. Instead I am adding an additional public method for every private method I want to test. I call this additional method Test-Port and denote them with the prefix t_. This Test-Port method then simply accesses the according private method.

Additionally I add a boolian flag to the Test-Port method to decide whether I grant access to the private method through the Test-Port method from outside. This flag is then set globally in a static class where I place e.g. other global settings for the application. So I can switch the access to the private methods on and off in one place e.g. in the corresponding unit test.

What if your test classes are in the same package as the class that should be tested?

But in a different directory of course, src & classes for your source code, test/src and test/classes for your test classes. And let classes and test/classes be in your classpath.

I recently had this problem and wrote a little tool, called picklock, that avoids the problems of explicitly using the java reflection api, two examples:

Calling Methods, e.g. private void method(String s) - by Java reflection

Method method = targetClass.getDeclaredMethod("method", String.class);
method.setAccessible(true);
return method.invoke(targetObject, "mystring");

Calling Methods, e.g. private void method(String s) - by Picklock

interface Accessible {
  void method(String s);
}

...
Accessible a = ObjectAccess.unlock(targetObject).features(Accessible.class);
a.method("mystring");

Setting Fields, e.g. private BigInteger amount; - by Java reflection

Field field = targetClass.getDeclaredField("amount");
field.setAccessible(true);
field.set(object, BigInteger.valueOf(42));

Setting Fields, e.g. private BigInteger amount; - by Picklock

interface Accessible {
  void setAmount(BigInteger amount);
}

...
Accessible a = ObjectAccess.unlock(targetObject).features(Accessible.class);
a.setAmount(BigInteger.valueOf(42));

Category: java Time: 2008-08-29 Views: 1

Related post

  • How to mock private method of another Class other than the Class under test using PowerMock? 2016-02-17

    I have a class which I would like to test with a public method that calls the private method of another class. When I try calling the private method of the same class, everything works perfectly. The problem occours when I try to mock another private

  • How to cover pagereference method in test class 2016-01-02

    I have a method like page reference method in my class. How to cover the pagereference method in test class??? all the other methods were covered except the pagereference method. I tried like: PageReference pageRef = Page.myclassname; Test.setCurrent

  • Unit test private method in c++ using a friend class 2014-09-30

    I know that this is a debated practice, but let's suppose that this is the best option for me. I am wondering about what is the actual technique to do this. The approach that I see is this: 1) Make a friend class that of the class who's method I want

  • how to call private method in test class to acheive code coverage 2016-02-14

    //Method returns last date of fiscal year private date getFiscalLastDate(){ Integer currentFY; Integer currentFYMonth; Integer CurrentFYDays; Date today; Date FYStartDate; Date FYEndDate; Organization orgInfo = [SELECT FiscalYearStartMonth, UsesStart

  • How can allow the method in routes using laravel 5? 2016-02-06

    I'm trying to execute the method but it does not working. I know it is very basic and may be ask more time, but i didn't resolve. Controller <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Http\Contro

  • How to create a frequency doubler circuit using only flipflops/ Digital elements? 2015-04-24

    First things first, is it even possible to scale up the frequency using only digital elements, atleast approximately? Though a frequency divider circuit can be designed very easily with flipflops. In the circuit I'm designing, there is no option left

  • css: how to create gap between vertical divs, using only one css instruction 2016-02-13

    How to create a vertical gap between the only neighboring blocks, but not between the parent elements, using only one css instruction. <div>BLOCK1</div> <div> <!-- vertical gap disabled --> <div>BLOCK2.1</div> <!-- v

  • How can I label conversations in Gmail using only the keyboard? 2011-03-05

    I don't like using the mouse. It's slower than knowing keyboard shortcuts really well and using them. I want to label conversations in my Gmail inbox using only the keyboard. Couldn't find anything useful in the Gmail keyboard shortcut list. Is there

  • How Do I Restrict VMWare Workstation to Use Only Eth1 directly? 2015-11-04

    My machine has two ethernet ports. I want to make VMWare exclusively use Eth1. I have a fresh install of Xubuntu Core 15.10 (amd64). I installed VMWare Workstation 12. It would not run, until I did this. The VMWare virutal network editor will not run

  • How to access Private Methods in Unit Tests Swift 2.0 Xcode7 2015-04-20

    I'm writing a BDD unit test for a public method. The method changes a private class member (private var) so I'd like to write an expect() and reassure it's being set correctly. Since it's private, I can't work out how access it from the unit test tar

  • How to call Finder Method with Parameters using BCS Runtime Model 2012-07-08

    Hi i have created BCS model which use secure store service for authentication to External system.Everything works fine using out of box external list and BCS webparts but i want to create custom webpart so i need to call finder method in webpart prog

  • How to calculate Private Key in RSA using Extended Euclidean Algorithm 2013-01-03

    When given $p = 5, q = 11, N = 55$ and $e = 17$, I'm trying to compute the RSA private key $d$. I can calculate $\varphi(N) = 40$, but my lecturer then says to use the extended Euclidean algorithm to compute $d$. That's where I get stuck. Here's my w

  • How to download private file from s3 using PHP? 2016-01-19

    I have saved a file in amazon s3 bucked as a private file now I want to download this file. I am using amazon s3 PHP component my download function is as below but I am getting exception [403] Unexpected HTTP status function downloadPrivateFile($buck

  • How to cover Boolean method in Test Class? 2016-01-20

    Here is the Code. public with sharing class page1 { @TestVisible private integer totalRecs = 0; @TestVisible private integer index = 0; public integer blockSize = 5; public page1(ApexPages.StandardController controller) { totalRecs = [select count()

  • How to get private key on IOS used for SSL traffic? 2014-01-23

    I need to debug/view an IOS app's encrypted traffic, so i had captured SSL encrypted TCP packets via pirni. and trying to decrypt them via Wireshark. but i need private key for that. is there any way to export private key in IOS to be used with wires

  • How to config private IPs for IPMI using VPN? 2015-01-12

    Recently I discovered it is best to protect my IPMI web interface behind a VPN. I went ahead and installed OpenVPN on my server and connect to it using tunnleblink on OSX. The VPN part is all set and done. Works flawlessly. My problem is that I do no

  • How to call controller method in SharePoint using csom 2016-07-01

    I have written a method in controller for getting data from sql database . now I want to call that method using CSOM so that I can display datalist in share point.

  • Is it OK to introduce methods that are used only during unit tests? 2011-06-24

    Recently I was TDDing a factory method. The method was to create either a plain object, or an object wrapped in a decorator. The decorated object could be of one of several types all extending StrategyClass. In my test I wanted to check, if the class

  • How do I create a VPN connection using only the terminal (SSH)? 2012-07-10

    I am trying to create a VPN connection for my Ubuntu Server machine to use. I only have access via ssh terminal session. I have seen many articles detailing how to connect to an existing connection, but none about creating a new connection. I am usin

iOS development

Android development

Python development

JAVA development

Development language

PHP development

Ruby development

search

Front-end development

Database

development tools

Open Platform

Javascript development

.NET development

cloud computing

server

Copyright (C) avrocks.com, All Rights Reserved.

processed in 3.524 (s). 13 q(s)