{"id":1523,"date":"2017-03-21T18:46:28","date_gmt":"2017-03-21T13:16:28","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=1523"},"modified":"2017-03-29T10:26:31","modified_gmt":"2017-03-29T04:56:31","slug":"test-class-private-methods-fields-inner-classes","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/test-class-private-methods-fields-inner-classes\/","title":{"rendered":"[ Solved -7 Answers ] JAVA &#8211; How to test a class that has private methods, fields or inner classes"},"content":{"rendered":"<ul>\n<li>Private method is a which can be invoked by code in the same class. It is not inherited by subclasses.<\/li>\n<li>A field is a class, interface, or enum with an associated value.<\/li>\n<li>Methods in the java.lang.reflect.Field class can retrieve information about the field, such as its name, type, modifiers, and annotations.<\/li>\n<li>Java inner class or nested class is a class i.e. declared inside the class or interface. We use inner classes to logically group classes and interfaces in one place so that it can be more readable and maintainable. Additionally, it can access all the members of outer class including private data members and methods.<\/li>\n<\/ul>\n<p><label class=\"label label-info\">SOLUTION 1<\/label><\/p>\n<ul>\n<li>A legacy application, we are not allowed to change the visibility of our methods, the best way to test private methods is to use reflection.<\/li>\n<li>Internally we\u2019re using helpers to get\/set private and private static variables as well as invoke private and private static methods.<\/li>\n<li>The following patterns related to the private methods and fields. We can\u2019t change private static final variables through reflection.<\/li>\n<\/ul>\n[pastacode lang=\u201djava\u201d manual=\u201dMethod%20method%20%3D%20targetClass.getDeclaredMethod(methodName%2C%20argClasses)%3B%0Amethod.setAccessible(true)%3B%0Areturn%20method.invoke(targetObject%2C%20argObjects)%3B%0A\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n[ad type=\u201dbanner\u201d]\n<h4 id=\"and-for-fields\"><span style=\"color: #ff6600;\"><strong>And for fields:<\/strong><\/span><\/h4>\n[pastacode lang=\u201djava\u201d manual=\u201dField%20field%20%3D%20targetClass.getDeclaredField(fieldName)%3B%0Afield.setAccessible(true)%3B%0Afield.set(object%2C%20value)%3B%0A\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n<h4 id=\"notes\"><span style=\"color: #000000;\"><strong>Notes:<\/strong><\/span><\/h4>\n<p>1. targetClass.getDeclaredMethod(methodName, argClasses) is looks like private methods. The same thing applies for getDeclaredField.<br \/>\n2. The setAccessible(true) is required.<\/p>\n<p><label class=\"label label-info\">SOLUTION 2<\/label><\/p>\n<h4 id=\"two-examples-of-where-we-need-to-test-a-private-method\"><span style=\"color: #000000;\"><strong>Two examples of where we need to test a private method:<\/strong><\/span><\/h4>\n<h4 id=\"decryption-routines\"><span style=\"color: #993366;\">Decryption routines \u2013<\/span><\/h4>\n<p>we 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)<\/p>\n<h4 id=\"creating-an-sdk-for-community-consumption\"><span style=\"color: #ff6600;\">Creating an SDK for community consumption.<\/span><\/h4>\n<p>Here public takes on a wholly different meaning, since this is code that the whole world may see (not just internal to my application). We put code into private methods if we don\u2019t want the SDK users to see it \u2013 we don\u2019t see this as code smell, merely as how SDK programming works. But we need to test my private methods, and they are where the functionality of my SDK actually lives.<\/p>\n<p>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<\/p>\n<p><label class=\"label label-info\">SOLUTION 3<\/label><\/p>\n<p>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.<\/p>\n<p>We can use the\u00a0junitx.util.PrivateAccessor package.<\/p>\n[pastacode lang=\u201djava\u201d manual=\u201dimport%20junitx.util.PrivateAccessor%3B%0A%0APrivateAccessor.setField(myObjectReference%2C%20%22myCrucialButHardToReachPrivateField%22%2C%20myNewValue)%3B%0APrivateAccessor.invoke(myObjectReference%2C%20%22privateMethodName%22%2C%20java.lang.Class%5B%5D%20parameterTypes%2C%20java.lang.Object%5B%5D%20args)%3B\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n<p><label class=\"label label-info\">SOLUTION 4<\/label><\/p>\n<p>In the Spring Framework we can test private methods using this method:<\/p>\n<p>ReflectionTestUtils.invokeMethod()<\/p>\n<h4 id=\"for-example\"><span style=\"color: #000000;\"><strong>For example:<\/strong><\/span><\/h4>\n<p>ReflectionTestUtils.invokeMethod(TestClazz, \u201ccreateTest\u201d, \u201cinput data\u201d);<\/p>\n<p><label class=\"label label-info\">SOLUTION 5<\/label><\/p>\n<p>Generic function to test private fields:<\/p>\n[pastacode lang=\u201djava\u201d manual=\u201dprotected%20%3CF%3E%20F%20getPrivateField(String%20fieldName%2C%20Object%20obj)%0A%20%20%20%20throws%20NoSuchFieldException%2C%20IllegalAccessException%0A%20%7B%0A%20%20%20%20Field%20field%20%3Dobj.getClass().getDeclaredField(fieldName)%3B%0A%0A%20%20%20%20field.setAccessible(true)%3B%0A%20%20%20%20return%20(F)field.get(obj)%3B%0A%7D\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n[ad type=\u201dbanner\u201d]\n<p><label class=\"label label-info\">SOLUTION 6<\/label><\/p>\n<p>If using Spring, ReflectionTestUtils provides some tools that help out with minimal effort.<\/p>\n<p>For example, to set up a mock on a private member without being forced to add an undesirable public setter:<\/p>\n<p>ReflectionTestUtils.setField(theClass, \u201ctheUnsettableField\u201d, theMockObject);<\/p>\n<p><label class=\"label label-info\">SOLUTION 7<\/label><\/p>\n<h4 id=\"using-the-java-reflection-api-two-examples\"><span style=\"color: #800000;\"><strong>Using the Java reflection API, Two examples:<\/strong><\/span><\/h4>\n<p>Calling methods, e.g. private void method(String s) \u2013 by Java reflection<\/p>\n[pastacode lang=\u201djava\u201d manual=\u201dMethod%20method%20%3D%20targetClass.getDeclaredMethod(%22method%22%2C%20String.class)%3B%0Amethod.setAccessible(true)%3B%0Areturn%20method.invoke(targetObject%2C%20%22mystring%22)%3B\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n<p>Calling methods, e.g. private void method(String s) \u2013 by Picklock<\/p>\n[pastacode lang=\u201djava\u201d manual=\u201dinterface%20Accessible%20%7B%0A%20%20void%20method(String%20s)%3B%0A%7D%0A%0A\u2026%0AAccessible%20a%20%3D%20ObjectAccess.unlock(targetObject).features(Accessible.class)%3B%0Aa.method(%22mystring%22)%3B%0A\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n[ad type=\u201dbanner\u201d]\n<p>Setting fields, e.g. private BigInteger amount; \u2013 by Java reflection<\/p>\n[pastacode lang=\u201djava\u201d manual=\u201dField%20field%20%3D%20targetClass.getDeclaredField(%22amount%22)%3B%0Afield.setAccessible(true)%3B%0Afield.set(object%2C%20BigInteger.valueOf(42))%3B%0A\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n<p>Setting fields, e.g. private BigInteger amount; \u2013 by Picklock<\/p>\n[pastacode lang=\u201djava\u201d manual=\u201dinterface%20Accessible%20%7B%0A%20%20void%20setAmount(BigInteger%20amount)%3B%0A%7D%0A%0A\u2026%0AAccessible%20a%20%3D%20ObjectAccess.unlock(targetObject).features(Accessible.class)%3B%0Aa.setAmount(BigInteger.valueOf(42))%3B%0A\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n","protected":false},"excerpt":{"rendered":"<p>Private method is a which can be invoked by code in the same class. It is not inherited by subclasses. A field is a class, interface, or enum with an associated value. Methods in the java.lang.reflect.Field class can retrieve information about the field, such as its name, type, modifiers, and annotations. Java inner class or [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2139],"tags":[3132,3124,3116,3117,3120,3121,3119,3129,3126,3131,3130,3118,3123,3122,3127,3128,3125],"class_list":["post-1523","post","type-post","status-publish","format-standard","hentry","category-java","tag-visiblefortesting-junit","tag-calling-other-class-methods-in-unit-testing","tag-how-do-you-assert-that-a-certain-exception-is-thrown-in-junit-4-tests","tag-how-do-you-unit-test-private-methods","tag-how-to-test-an-anonymous-inner-class-that-calls-a-private-method","tag-how-to-test-passing-of-time-in-junit-test-without-accessing-private-variables","tag-how-to-write-a-junit-test-for-a-class-that-uses-a-network-connection","tag-junit-set-private-field","tag-junit-test-private-methods-mockito","tag-junit-test-private-methods-reflection","tag-powermock-test-private-method","tag-should-i-unit-test-methods-which-are-inherited-from-super-class","tag-tdd-how-to-create-tests-that-tests-init-value","tag-test-driven-development-how-to-write-a-test-before-none-of-implementation-code-exists","tag-testing-private-methods-java","tag-unit-test-private-methods-c","tag-unit-testing-private-fields"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/1523","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=1523"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/1523\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=1523"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=1523"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=1523"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}