Unit test methods of a private inner class

I have a class A that has an internal cache represented by class B. this inner class is private as the cache should not be visible to external consumers and only needs to help external class A. I am using Jmock and Java

public class A {
    ...
    private class B {
    ... 
       public void testMethod() {
          //The method I want to unit test
          ...
       }
    }
}

      

This is shown above. I'm not sure how to unit test testMethod () which is from the private inner class B (since class B is not visible to the outside world).

Please advise!

Thank!

+3


source to share


4 answers


since the cache should not be visible to external consumers

A unit test is an external consumer. It is a class that calls the functionality of the object under test just like any other class.

Caveat: There are many opinions and discussions on this issue. What I present here is not a "one true answer", but based on my own experience in running unit tests in code.

Don't close the private members of the unit test. Not only does it usually take a bit of trickery for this to happen, it creates a relationship between classes. (Test class and tested class). Violation of object-oriented principles is a violation of internal and related principles.



Instead of thinking about your tests in terms of the methods you call on the class, think about your tests in terms of the functionality you call on the device. No matter what features are exposed, this is something to check.

This leads to several conclusions:

  • If there is no public function that internally calls private members, then why are these private members there at all? Just remove them.
  • If the private functionality is very complex and very difficult to call / test using only public functions, perhaps some refactorings are simplifying the class.

Since the code that uses this object can only call public functionality, the code that checks the object should only check the public functions.

+7


source


Testing private methods / classes is not recommended. To test a parent method that calls private methods, it is enough to check that you can assert / validate the influence of the private class.

eg,



if your inner class changes some value in the database, you can call the parent method and can assert against the db values. This will ensure that your private methods / private inner classes are validated.

refer: unit testing of private methods

+3


source


If you are strictly following the TDD approach, private methods and private inner classes are only the result of the red / green / refactor refactoring step .

So the approach should be:

  • Write tests that validate the public interface of the class, including this caching behavior and write code, so that these tests pass as they come. This will lead to lengthy public methods and some fields that are explicitly related to caching only.
  • Then refactor some of the cache-related private methods from the long public methods.
  • The next step is to move the private cache fields and methods into a private inner class. After each refactoring, the tests should pass unchanged.

You will end up with privates methods, which are fully tested, but only through the public interface.

+3


source


As said above, you have to rethink why you are testing a private method, and I won't go into that anymore as others have provided some good information.

However, if there is a need to still test the private method, use reflection to "unlock" the private method and use Apache Commons to avoid having to write generic code (DRY - Do not Repeat Yourself) https://commons.apache.org/proper /commons-lang/javadocs/api-2.6/org/apache/commons/lang/reflect/package-summary.html

If you need to mock a private method, like a DB call that is done in a private method of a class. Again, the best way is to redesign it so that the DB component is abstracted, but if you need to do that, consider PowerMock

https://code.google.com/p/powermock/wiki/MockPrivate

+1


source







All Articles