Article Discussion
Testing Private Methods with JUnit and SuiteRunner
Summary: This article compares four different approaches to testing private methods in Java classes.
26 posts.
The ability to add new comments in this discussion is temporarily disabled.
Most recent reply: April 28, 2015 4:22 PM by Syed
    Bill
     
    Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
    Testing Private Methods with JUnit and SuiteRunner
    May 23, 2004 8:00 PM      
    This article compares four different approaches to testing private methods in Java classes.

    http://www.artima.com/suiterunner/private.html

    Do you test private methods? If not, why not? If so, how do you prefer to test them?
    • Jeff
       
      Posts: 1 / Nickname: jeffrey460 / Registered: May 24, 2004 10:03 PM
      Re: Testing Private Methods with JUnit and SuiteRunner
      May 25, 2004 2:07 AM      
      I agree with the post above. If a generic algorithm can be pulled out into a private method, it can probably be pulled into a seperate class that is used by the currently tested class. Then you can write tests for it. I.e. another class is probably struggling to come out.

      If it is only called by one method that does not mean there is a problem with creating a class to hold it and any potential brethren. Rather than worry about a class's client list, worry about how the class's cohesion.
      • Bill
         
        Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
        Re: Testing Private Methods with JUnit and SuiteRunner
        May 25, 2004 11:53 AM      
        > I agree with the post above. If a generic algorithm can
        > be pulled out into a private method, it can probably be
        > pulled into a seperate class that is used by the currently
        > tested class. Then you can write tests for it. I.e.
        > another class is probably struggling to come out.
        >
        > If it is only called by one method that does not mean
        > there is a problem with creating a class to hold it and
        > any potential brethren. Rather than worry about a class's
        > client list, worry about how the class's cohesion.

        Well, it is always true that anything that can be pulled out into a private method could alternatively be placed in a separate class. If you make that class package access, then you can write tests for it. I refer to this as "approach 2" in the article. But you need not actually pull it into another class to test it that way, you can just delete the word private and make the method is package access where it sits.

        As far as cohesion goes, the reason to worry about cohesion is to make the code easier for humans to understand. That's the real goal. And a class with one static method to me does not carry its weight. You have now added another class to the package-level API, and it will be in people's faces to some extent, and they'll have to do a bit of work to realize they don't need to care about it because it is only used in one place. Occasionally, you will see a class that only contains a bunch of static methods. This is fine, but it is rather rare, and a class that contains only one static method and which is needed by only one other class really calls to me to be moved into that class and made into a private method. That's the kind of thing private methods are for in my book (which I should probably write someday.)

        There is no perfect design, and different people prefer different things. Some people don't mind turning private methods into package access for the sake of testing. But some people do mind, and for them, they can use any of the other 3 approaches I list in the article. I am curious to hear how other people reading this prefer to deal with the testing private methods issue.
    • Carl
       
      Posts: 3 / Nickname: cmanaster / Registered: June 3, 2003 3:30 AM
      Re: Testing Private Methods with JUnit and SuiteRunner
      May 25, 2004 1:05 AM      
      Bill, your parseArgsIntoLists function screamed duplication to me.

      Does it indicate that parseArgsIntoLists should be moved into another class to promote reusability, as the JUnit FAQ suggests? Would Dave and Andy say its a warning sign that there's another class in there struggling to get out?

      Yes and yes, imnsho.

      I don't know Java, so the following probably doesn't work, and you may not care for the brace alignment, but it conveys, to me a much clearer sense of what is happening than the original code (and I'm sure real working Java could be written that looks more like this):

      switch args[ i].firstTwoCharacters()
      	{
      	case "-p": addNextTwoArguments(runpathList, i);
      	case "-g",
      	     "-o",
      	     "-e": reportersList.add(args[ i])
      	case "-f",
      	     "-r": addNextTwoArguments(reportersList, i);
      	case "-s": addRemainingArguments(suitesList, i);
      	default:   throw new IllegalArgumentException("Unrecognized argument: "
                              + args[ i]);
      


      And here's a bug (well, undesired behavior at least): in the web formatting code: since the java code includes bracket-i-bracket, it italicizes everything after(I'm adding spaces to prevent that...)
      Peace,
      --Carl
      • Bill
         
        Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
        Re: Testing Private Methods with JUnit and SuiteRunner
        May 25, 2004 11:41 AM      
        > I don't know Java, so the following probably doesn't work,
        > and you may not care for the brace alignment, but it
        > conveys, to me a much clearer sense of what is happening
        > than the original code (and I'm sure real working Java
        > could be written that looks more like this):
        >
        >
        > switch args[ i].firstTwoCharacters()
        > 	{
        > 	case "-p": addNextTwoArguments(runpathList, i);
        > 	case "-g",
        > 	     "-o",
        > 	     "-e": reportersList.add(args[ i])
        > 	case "-f",
        > 	     "-r": addNextTwoArguments(reportersList, i);
        > 	case "-s": addRemainingArguments(suitesList, i);
        > default:   throw new
        > w IllegalArgumentException("Unrecognized argument: "
        >                         + args[ i]);
        > 
        

        >
        As you guessed, you can't do that in Java. Java requires that the expression that comes in the parentheses following a switch be an int. The same is true, therefore, of the case statements. When it comes to switching on the semantic value of Strings, which is what this method does, you must in Java use a series of if-else statements.
      • Bill
         
        Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
        Re: Testing Private Methods with JUnit and SuiteRunner
        May 25, 2004 0:00 PM      
        > And here's a bug (well, undesired behavior at least): in
        > the web formatting code: since the java code includes
        > bracket-i-bracket, it italicizes everything after(I'm
        > adding spaces to prevent that...)

        Yes I'm aware of that one, and I did fix it once. The problem stems from the interplay between two different filters that come with Jive Forums, which I use underneath for the forums here at Artima. Quite a while back I replaced one of their filters with one I wrote myself (that algorithm was actually the very first thing I did test-first). That solved the problem, but I later upgraded to a new version of Jive that had a bunch of breaking changes to their APIs. One of the things that broke was that filter, so I went back to using their old one which has the problem still. What's worse is that the code markup doesn't work anymore, because that was something I added in my filter. It is on our list, but hasn't bubbled up high enough to get attention yet.
    • John
       
      Posts: 1 / Nickname: johnowen / Registered: June 2, 2004 6:39 AM
      Re: Testing Private Methods with JUnit and SuiteRunner
      June 2, 2004 11:18 AM      
      How about using xdoclet or annotate metadata to help you generate testable code? The code for the method(s) with a specific annotation could be copied to a test-friendly source file with test-friendly access and be incorporated into your test suite.
      • Bill
         
        Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
        Re: Testing Private Methods with JUnit and SuiteRunner
        June 2, 2004 11:33 AM      
        > How about using xdoclet or annotate metadata to help you
        > generate testable code? The code for the method(s) with a
        > specific annotation could be copied to a test-friendly
        > source file with test-friendly access and be incorporated
        > into your test suite.

        It sounds like both you and Calum are suggesting ways to autonomously modify the source code, or make a second more testable copy, that converts the private to package access. Perhaps this is a fifth approach. One trouble I forsee with taking such an approach is that it might be hard to get IDEs like IntelliJ and Eclipse to not complain that I'm trying from my test to invoke an inaccessible private method. I could conceivably do it the other way, and have the tool transform marked methods from package access to private for deployment. The problem I have with that is that then my IDE wouldn't be warning me when I invoke an inaccessible private method from a non-test class. Another issue I would have with doing it this way is I think it would be a bit confusing to the newcomer.

        None of the four approaches I listed in the article are perfect. They each have advantages and disadvantages. Going in and autonomously modifying the source code (or the binaries for that matter) for the test also has advantages and disadvantages. I wouldn't want to do it this way given my current circumstances, but someone out there may be in a situation for which this is a reasonable approach.
    • Jean
       
      Posts: 2 / Nickname: lazarou / Registered: October 5, 2003 6:46 PM
      Re: Testing Private Methods with JUnit and SuiteRunner
      June 3, 2004 0:19 AM      
      I won't talk about the use and misuse of testing private methods (or fields), I just can't add any better idea.

      But let's talk about the example with the argument list parsing. I recently used a PDF library to merge PDF files, as I was in a hurry and didn't want to dive into the APIs, I just called the main method of a "tool" class, passing the arguments as strings instead of calling a java method with the correct arguments.

      Based on this experience, I thought we could see "main" methods as beeing a public interface for calling black box services. If you do agree with this point, what do you think about saying that the parse arguments method also could be a public method? So client code could validate the way it calls the public interface (maybe in some test code).

      Think of arguments as a "serialized" list of objects...

      I am not saying we always should turn private methods we want to test to some public service, it just happened I don't really like the "main(String[] args)" way to startup a program.

      Jean Lazarou

      PS:
      (1) The generic body of a main method could be :
      (a) set default startup parameters
      (b) parse and validate arguments, produce the startup
      parameters
      (c) call the actual startup method with the startup
      parameters (the startup method is type safe but
      could require some kind of MyParameters object)
      - the startup method is not to be static .

      (2) What about starting programs with a command line like :

      > java my.package.MyClass@aMethod 528 "Hello, World!"

      with the MyClass class beeing:

      > class MyClass {
      > public String aMethod(int i, String s) { ... }
      > }
    • Calum
       
      Posts: 1 / Nickname: calummacle / Registered: February 11, 2003 0:04 PM
      Re: Testing Private Methods with JUnit and SuiteRunner
      May 28, 2004 4:40 AM      
      While I haven't actually tried this, I was wondering about the possibility of using AOP to help with this.

      The idea would be that you would use aspects to change your private methods to be public, and then your test code would be compiled and run against the "aspectized" version, rather than the original version.

      Some potential practical issues:

      1. I don't know if any AOP libraries currently support changing accessibility of methods.

      2. A private method in a superclass, made public, may clash with an existing method in a subclass.

      3. Things like refactoring wouldn't work properly, as you'd be refactoring the original source with private methods.

      Anyway, just a thought... don't know if it would work in practice or not.
      • E.
         
        Posts: 2 / Nickname: en / Registered: February 17, 2003 9:36 PM
        Re: Testing Private Methods with JUnit and SuiteRunner
        June 21, 2004 2:09 PM      
        "... While I haven't actually tried this, I was wondering about the possibility of using AOP to help with this..."

        So was I :-)

        At first I did think: Well, if I can introduce new methods and parents with aspects then surely I can also introduce a new inner class (Suggestion 3)... But alas, no such luck (in AspectJ, anyway).

        But then noticed this:

        If I specify an aspect as privileged then I can access private fields and methods.

        So here is what I will do in the future:

        public class A {
           
           private boolean privateMethod() {
              return true;
           }
           
        }
        


        will have its private parts tested by

        public privileged aspect ATest extends TestCase {
         
              public void testPrivateMethodInA() {
                 A a= new A();
                 Assert.assertTrue(a.privateMethod());
              }
         
        }
        


        :-) And the best part is.. It works! :-)

        (And btw, I did this with JUnit and AspectJ on Eclipse 3.0RC1. And note that for some reason I need to put the aspect (ATest) and the AllTests class in the default package to make it work...)
    • Jeff
       
      Posts: 1 / Nickname: jlangr / Registered: October 27, 2003 7:07 AM
      Re: Testing Private Methods with JUnit and SuiteRunner
      June 22, 2004 2:01 PM      
      Nice article; I've wanted to see a discussion on these categorizations for some time now. Some random thoughts:

      -I've used all but the third technique (inner test class). The only time I've found the reflective cheat useful enough to warrant the ugliness is in an "assertFieldsEqual" method.

      -If I'm building a private method that is so complex that I need to address its functionality separately (i.e. such that I can't effectively create it through testing of the public interface), I've found that more often than not it contains some commonly useful abstraction. So I'll typically expose it to package level and write the test. Then, *depending on my level of laziness*, and the extent to which I think I've found something useful, I'll extract it to a separate class.

      I don't have a problem with a one-method, single-use utility class. Theoretically, I'm not gonna need it. What I find, though, is that the existence of this class often triggers other developers to notice it and use the common abstraction. (Pairing doesn't always catch everything.)

      -The bigger sin than exposing a private method to package level access is the tighter coupling that comes as a result of testing implementation details. The technique--whether you change the access modifier or use reflection--doesn't matter. I can trust that developers of classes in the same package won't abuse the exposed method (and if they do, so what; that's why I have tests). That's not what I'm worried about; perfect design be damned. The problem is that you can no longer refactor the production class as easily.

      On occasion, this is OK. Taken too far, your system becomes stagnant and brittle, something I've seen in practice. Small refactorings that should take seconds and should have no impact instead break tests, which then require tens of minutes of attention. (This is an even bigger problem when people similarly violate encapsulation using "method-sequence mocking.")

      -Jeff-
    • Charles
       
      Posts: 1 / Nickname: repoman / Registered: April 1, 2002 2:20 PM
      Re: Testing Private Methods with JUnit and SuiteRunner
      June 23, 2004 1:50 AM      
      Hi Bill,

      I quite enjoy your articles and am patiently awaiting the completion of your book(s). However, regarding this topic, I'd like to point out what I consider to be a violation of a unit testing "tenet" (if I may call it that), regardless of the scope of the method(s) under test.

      Perhaps you have done this for the sake of brevity in your article, but I noticed that your test method (testParseArgsIntoLists) actually consists of 7 distinct tests. Best practice (as far as I know it) dictates that each test should exist within a distinct test method. By placing them all into a single monolithic test method, you not only obscure the distinction between the individual tests, but you also create an "all or nothing" test.

      This means that if one of the 7 tests fail, they all fail in a sense. That is, you are unable to readily see that perhaps 6 of the 7 might actually succeed and therefore cannot as quickly identify the particular test that failed.

      More precisely, all tests (in your monolithic test method) that follow the failed test will remain untested until the failed test is made to pass, so you will never see all failures and all successes at once, as you would if you used 7 separate test methods.

      Sorry this is a bit off topic, but I thought it was worth pointing out.

      Cheers,
      Chuck
    • Bruce
       
      Posts: 5 / Nickname: beckel / Registered: June 3, 2003 6:54 AM
      Re: Testing Private Methods with JUnit and SuiteRunner
      June 4, 2004 8:41 AM      
      Private methods are typically pieces of duplicate code that have been refactored from other methods. Thus, the "indirect testing" concept is going to work fine, and you will not need to directly test private methods in the large majority of situations.

      While this is mildly interesting, I think you're solving the wrong problem here. IMO, a much more important problem is that too much ceremony is required to create unit tests. What we need is a simpler way to create and maintain unit tests.
      • Bill
         
        Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
        Re: Testing Private Methods with JUnit and SuiteRunner
        June 4, 2004 10:27 AM      
        > Private methods are typically pieces of duplicate code
        > that have been refactored from other methods. Thus, the
        > "indirect testing" concept is going to work fine, and you
        > will not need to directly test private methods in the
        > large majority of situations.
        >
        In the article my conclusion is that testing private methods indirectly will likely be the best choice most of the time, but not always. Just this week I had the problem again, while working on the Java app that formats the pages for this website. The problem came up in the usual way, not when I was factoring out duplicate code from multiple methods into a private method, but when I just had a private method for the sake of making the calling method easier to understand. As with the example I used in the article, the calling method was main(). I used my usual approach to test the private method, approach 2 in the article. I made the method package access.

        > While this is mildly interesting, I think you're solving
        > the wrong problem here. IMO, a much more important problem
        > is that too much ceremony is required to create unit
        > tests. What we need is a simpler way to create and
        > maintain unit tests.

        What ceremony is that? The ceremony of adding test methods to test cases or suites doesn't seem overly burdensome to me. I know you prefer to have the test code next to the production code, but you can do that with JUnit or SuiteRunner by putting declaring the test class as a nested class inside the production class it is testing. You could also script the tests with Groovy or Jython, but I don't think that will really reduce much ceremony. Are you perhaps feeling the urge for something more like precondition, postconditions, and invariants a la Eiffel?
      • Rick
         
        Posts: 3 / Nickname: rkitts / Registered: January 27, 2003 4:30 PM
        Re: Testing Private Methods with JUnit and SuiteRunner
        June 6, 2004 8:24 AM      
        > While this is mildly interesting, I think you're solving
        > the wrong problem here. IMO, a much more important problem
        > is that too much ceremony is required to create unit
        > tests. What we need is a simpler way to create and
        > maintain unit tests.

        Can you expand on this? What do you mean by ceremony? I tend to agree unit tests can be tedious to write, though I've found that extremely granular tests are substantially easier to write and maintain.
      • scot
         
        Posts: 1 / Nickname: scotartt / Registered: February 24, 2004 9:56 AM
        Code coverage tools Re: Testing Private Methods
        June 22, 2004 3:57 PM      
        I don't test private methods. But I know when they are tested (or not); if you use a code coverage tool like Clover (or others) you will find out exactly when a private method is not covered in your tests and when particular code blocks aren't tested. You'll discover all the little boundary conditions and funny little combinations that you have to add to your tests in order to ensure your class maintains all of its expected behaviour. And you'll test your private methods, or at least know if it isn't, and exactly what parts of it aren't, being tested.
      • Vincent
         
        Posts: 40 / Nickname: vincent / Registered: November 13, 2002 7:25 AM
        Re: Testing Private Methods with JUnit and SuiteRunner
        June 7, 2004 7:42 AM      
        > Private methods are typically pieces of duplicate code
        > that have been refactored from other methods. Thus, the
        > "indirect testing" concept is going to work fine, and you
        > will not need to directly test private methods in the
        > large majority of situations.

        I'm not really convinced that this is really the case. If a piece of code warrants its own method than I feel that it's not unreasonable to say that it warrants its own testing, too.

        In particular, any method that is capable of producing different results depending upon a set of parameters or other conditions should have a set of tests that cover all the variations. Those tests should limit themselves to the method being tested and should not be encumbered with the added complexity of having to manipulate the public interface in order to induce specific behaviour in hidden methods.

        Further tests may be necessary to ensure that the private methods work as intended via the public interface but that is a separate issue to demonstrating that those methods work in their own right.

        Vince.
        • John
           
          Posts: 1 / Nickname: jlindwall / Registered: August 4, 2004 2:11 AM
          Re: Testing Private Methods with JUnit and SuiteRunner
          August 4, 2004 6:28 AM      
          > In particular, any method that is capable of producing
          > different results depending upon a set of parameters or
          > other conditions should have a set of tests that cover all
          > the variations. Those tests should limit themselves to
          > the method being tested and should not be encumbered with
          > the added complexity of having to manipulate the public
          > interface in order to induce specific behaviour in hidden
          > methods.
          >
          > Further tests may be necessary to ensure that the
          > private methods work as intended via the public interface
          > but that is a separate issue to demonstrating that those
          > methods work in their own right.

          I really enjoyed the original article and was excited to see someone wrestling with an issue that had bugged me for a long time. I too saw the majority telling me that its "wrong" to test anything but the public interface of a class. However that approach left me feeling unsatisfied.

          The poster above nicely elucidates the primary point in my mind: The point of unit testing is to isolate a "unit" (a method in this case) and exercise it. By doing so we immediately pinpoint the root cause of a failure. In contrast, a more black-boxish system/functional test might illustrate a failure condition in a system but it often requires research to determine the root cause of the failure. I want as much precision in my testing as possible to avoid this haze.

          Testing of a private method is obviously a more direct test of that unit (method) then the indirect test we get by testing the public methods that use it.

          In the past I've either skipped writing tests for the private scoped methods or (rarely) relaxed the scoping to package-level. I have looked at reflection-based approaches as mentioned in the article but to me that's just too much effort and complexity... it should not be that hard.

          I've just started using the excellent open-source code coverage tool, emma. Perhaps having a tool confirm that my indirectly invoked private methods are being exercised will make me relax my stance.

          It just smells so ... accidental.

          I'm willing to be swayed and some of the points made in this thread were fairly compelling. I'm really enjoying this discussion.
    • Brian
       
      Posts: 1 / Nickname: brianc / Registered: December 3, 2004 7:11 AM
      Re: Testing Private Methods with JUnit and SuiteRunner
      December 3, 2004 0:41 PM      
      Excellent article and interesting discussion. One approach I've been using in C# / Nunit is to promote private methods that I feel need to be tested to protected and then write a test class that overrides them. The test class method can access the base method implementation and either provide external visibility to it or implement the test logic itself.

      I find this approach also works well for hooking in 'mock methods' that override methods that e.g. access hardware or some external API with code that can be driven by the test framework via public test properties that only exist in the test class. In some cases these mock methods are simpler to implement and maintain than full-blown mock objects.

      The downside is that classes outside of the package can override the protected method as well, but it does leave the package-level and public API alone. Any potential issues with doing this in Java / JUnit?
    • Sreedevi
       
      Posts: 1 / Nickname: sreejaggu / Registered: November 14, 2005 5:16 PM
      Re: Testing Private Methods with JUnit and SuiteRunner
      November 14, 2005 10:31 PM      
      > This article compares four different approaches to testing
      > private methods in Java classes.
      >
      > http://www.artima.com/suiterunner/private.html
      >
      > Do you test private methods? If not, why not? If so, how
      > do you prefer to test them?


      Using method invokeStaticMethod() I was able to invoke private methods, but at the same time I need to access private variables to check the results of the test.Is it possible to get access to private variables, If so please tell me the method of doing it.


      Anyway using Junit I was able to invoke the private method,but when tried to launch through ant, the private accessibility would be detected and the ant build would fail.How to overcome this problem?
      Kindly let me know as soon as possible as, I am working on the same concept.

      Thanks,
      Sreedevi.
    • cityscope
       
      Posts: 1 / Nickname: ameney / Registered: November 6, 2005 5:43 PM
      Re: Testing Private Methods with JUnit and SuiteRunner
      November 21, 2005 6:49 PM      
      Do you konw what kind of companies can be setted up in China?
      There are three different business incorporation vehicles which can be utilised to do business in China. These are:
      1. The utilisation of a representative office
      2. Seeking a Chinese joint venture partner
      3. Establishing a Wholly Foreign Owned Enterprise (WFOE)
      Representative Office (RO):
      A representative office is just a subsidiary of a foreign company in China. If your are looking for a company, which needs a local presence to manage services or coordinate outsourcing business activities or research developing Chinese market, then a representative office is useful and inexpensive vehicles for establishing a presence in China. Main purposes of a representative office are conducting market research, monitoring purchasing activities, marketing and sales administration for sales conducted between China and your parent company etc. Representative offices cannot write bill for service or sales to their clients in China. However, you can act like a liaison in matter of ordering, shipping, collecting money and so on.

      Joint Venture:
      Joint venture is business where a foreign firm goes into businesses with local Chinese partners. Joint venture is usually established to exploit the market knowledge, preferential market treatment, and manufacturing capability of the Chinese side along with the technology, manufacturing know-how and marketing experience of the foreign partner.

      Wholly Foreign Owned Enterprise (WFOE):
      These are 100% foreign owned companies, originally developed for the specific purpose of encouraging foreign investment in manufacturing for export in Special Economic Zones (SEZs) in China, and they were prohibited from selling to the Chinese domestic market. Since a recent change in regulations, from 1 December 2004, WFOE's can now trade within China, and can sell wholly foreign manufactured goods in China. The capital requirements for such companies have also been dramatically reduced.

      so next time i will explain the benefits and disadvantages of them.

      If you are interested and want to konw more konwlege about it, you can goto the pages, we offer you four language websites:
      http://www.cityscopeinvestments.com
      Chinese one: http://www.cityscopeinvestments.cn
      German one: http://www.cityscopeinvestments.de
      French one: http://www.cityscopeinvestments.com/indexfr.htm
      and also you can contact us if you have questions:
      email:s.xie@cityscopeinvestments.com
      tel:+86 (21) 63298968
      fax:+86 (21) 63295886
      we will ensure to answer your questions in ten minutes!
    • artem
       
      Posts: 1 / Nickname: artemk / Registered: January 15, 2006 7:11 PM
      Re: Testing Private Methods with JUnit and SuiteRunner
      January 16, 2006 0:36 AM      
      As long as the private methods are the part of internal class inplementation, it could not be a business of unit tests to test them. But I do agree with the concept claiming that the testing of private methods is sometimes defensible and desirable thing. So, I suggest to use following approach: the class that have privates are need to be tested tests itself.

      Something like that:

      ClassA
      {
      private methodA();
      private methodB();

      public TestItself()
      {
      // test methodA
      // test methodB

      // if some test fails then throw an exception of some type, specifying numbers of tests that failed
      }
      }

      So, the unit test can only invoke the testItself() method of ClassA

      This allows us to test privates and do not violate the incapsulation
    • Omar
       
      Posts: 1 / Nickname: ub40 / Registered: March 1, 2007 8:59 PM
      Re: Testing Private Methods with JUnit and SuiteRunner
      March 2, 2007 2:59 PM      
      Hi,

      It is an excellent article, very well written and the arguments very well explained. I thoroughly enjoyed reading it.

      Until recently I did not test private methods, especially for classes that I had personally designed as I could ensure coverage of private methods via public methods within the test cases.

      Recently I was asked to migrate legacy code from one database platform to another. To optimise the entire exercise while keeping the code change to the absolute minimum, it was decided to only test the methods that were changed. Quite a lot of database access code is locked in private methods and these methods needed to be tested separately to validate the change.

      I used reflection successfully to invoke these methods and also to inspect the values of class fields before and after the tests.

      Reflection is, therefore in my opinion, probably an efficient and an appropriate mechanism to test a legacy class's private members where minimum change is required.
      • Gabriele
         
        Posts: 1 / Nickname: simpatico / Registered: March 17, 2011 9:10 AM
        Re: Testing Private Methods with JUnit and SuiteRunner
        March 17, 2011 2:19 PM      
        I just thought to bring to your attention a new embodiment of Approach 4: dp4j.com which injects the reflection API code at compile-time.
    • Mayur
       
      Posts: 1 / Nickname: mayur214 / Registered: October 1, 2013 7:42 PM
      Re: Testing Private Methods with JUnit and SuiteRunner
      October 2, 2013 0:48 AM      
      I have written test code using java reflection and JUnit with your reference code at suitrunner. But now I am stuck at one place where I want to test Handler(java.os.Handler). So I have written one Handler and its handleMessage() and passed it to invocation method to invoke private method of target class. But that private method is not sending Message back to the handler that I have written. What is the best way to invoke private Handlers? Reply ASAP.
    • Syed
       
      Posts: 1 / Nickname: sarmahdi / Registered: April 28, 2015 11:16 AM
      Re: Testing Private Methods with JUnit and SuiteRunner
      April 28, 2015 4:22 PM      
      Hello I am trying to figure out, after reading your article what to do with my code and how to improve it, I posted it at stackoverflow: http://stackoverflow.com/questions/29908171/junit-test-for-private-method

      My code is like this:

      ******************************************************


      public class DelegateHandler{
      Map<Integer,ActionHandlers> handlerMaps;

      public execute(Action action){
      populateActionHandlers(action);
      executeActionHandlers();

      }//end of execute

      //This method can create and populate more than one handlers in handlerMap
      private populateActionHandlers(action){
      handlerMap = new LinkedHashMap<ActionHandlers>();
      if (action.isMultimode()){
      handlerMap.add(1,new handler(action.getabc()));
      handlerMap.add(2,new handler(action.getabc()-1));
      }else{
      handlerMap.add(1,new handler(action));
      }

      }//end of populateActionHandlers

      //This method can execute more than one handlers in handlerMap
      private executeActionHandlers(){
      for(ActionHandler actionHandler : handlerMap.values){
      actionHandler.executeAction();
      }

      }//end of executeActionHandlers
      }

      ********************************************

      Can you tell me how to solve the code smell. i will really appreciate it. btw, I liked your blog article and I am trying to improve my code style and esp JUNIT tests.

      thanks
      Syed