{"id":112,"date":"2018-01-05T15:01:36","date_gmt":"2018-01-05T02:01:36","guid":{"rendered":"https:\/\/content.ronella.xyz\/apps\/wordpress\/?p=112"},"modified":"2018-12-14T15:34:17","modified_gmt":"2018-12-14T02:34:17","slug":"sample-conversion-of-difficult-to-class-to-testable-in-gosu","status":"publish","type":"post","link":"https:\/\/www.ronella.xyz\/?p=112","title":{"rendered":"Refactoring difficult class to test to testable in Gosu"},"content":{"rendered":"<p><strong>Use case<\/strong><\/p>\n<p>Normally if we like to create a utility class we normally implement it with static methods.<\/p>\n<p><strong>Problem<\/strong><\/p>\n<p>This is good if we can write unit tests on it. But most of the time this is not the case since it is difficult to write a unit on it. Specially, if the utility class that have a lots of static methods inside that depends on each other. For example, the following piece of code (i.e. Code 1) even though small authoring a test could be difficult.<\/p>\n<p><strong>Code 1. Small class that cannot be tested easily.<\/strong><\/p>\n<pre style=\"white-space: pre;\">package example\n\nuses java.lang.Math\n\nclass SampleCodeWithStaticMethods {\n\nprivate construct() {}\n\nstatic function myMethod() {\n var value = someAction() + 10\n print(value)\n }\n\nstatic function someAction() : int {\n return (Math.round(Math.random()*100) as int) + 100\n }\n\n}<\/pre>\n<p>Imagine write a unit test for myMethod. It is almost impossible because the method depends on someAction which is also a static method that returns random integer.<\/p>\n<p>We need to refactor this to make it testable. The first thing we can do is identify if there are other static methods being called that are not a member of the class and make a separate non-static method for them. From code 1, those static method calls are:<\/p>\n<p>- Print<br \/>\n- Math.round<br \/>\n- Math.random<\/p>\n<p>Call those new member instance methods in place of the static method call. Making them contained in a separate method allows us to bypass them by overriding on a child class (i.e. basic OOP principle).<\/p>\n<p>The next thing is remove all the static modifiers to convert all of them to member instance methods.<\/p>\n<p>The refactored code would be like the following code.<\/p>\n<p><strong>Code 2. Refactored to use non-static methods<\/strong><\/p>\n<pre style=\"white-space: pre;\">package example\nuses java.lang.Math\n\nclass SampleCodeWithoutStaticMethods {\n\n\/\/Contains the call the to static print method.\n function output(value : int) {\n print(value)\n }\n\n\/\/Contains the call the Math.round and Math.random.\n function random() : int {\n return (Math.round(Math.random()*100) as int)\n }\n\nfunction myMethod() {\n var value = someAction() + 10\n \/\/Calls the member method that contains the static print method.\n output(value)\n }\n\nfunction someAction() : int {\n return random() \/\/Calls the member method that contains the static Math.round and Math.random method.\n + 100\n }\n\n}<\/pre>\n<p>Now testing myMethod becomes so trivial (i.e. Code 3) using the very old behaviour of OOP (i.e. being polymorphic). The key is the inner class <strong>SampleCodeWithoutStaticMethodsMyMethod<\/strong> where we overrode someAction and output instance methods.<\/p>\n<p>The <strong>someAction method<\/strong> now just return 25 which makes it more consistent than its original random behaviour.<\/p>\n<p>The <strong>output method<\/strong> is just collecting what's being passed to it to <strong>result field<\/strong> instead of printing it.<\/p>\n<p><strong>Code 3. Unit test for myMethod<\/strong><\/p>\n<pre style=\"white-space: pre;\">package example\n\nuses gw.api.system.server.Runlevel\n uses gw.testharness.RunLevel\n\n@gw.testharness.ServerTest\n @RunLevel(Runlevel.NONE)\n class SampleCodeWithoutStaticMethodsTest extends gw.testharness.TestBase {\n\nclass SampleCodeWithoutStaticMethodsMyMethod extends SampleCodeWithoutStaticMethods {\n var result : int\n\noverride function someAction() : int {\n return 25\n }\n\noverride function output(value : int) {\n result = value\n }\n }\n\nfunction testMyMethod() {\n var testObj = new SampleCodeWithoutStaticMethodsMyMethod()\n testObj.myMethod()\n assertEquals(35, testObj.result)\n }\n\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Use case Normally if we like to create a utility class we normally implement it with static methods. Problem This is good if we can write unit tests on it. But most of the time this is not the case since it is difficult to write a unit on it. Specially, if the utility class [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[16],"tags":[],"_links":{"self":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/112"}],"collection":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=112"}],"version-history":[{"count":6,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/112\/revisions"}],"predecessor-version":[{"id":700,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/112\/revisions\/700"}],"wp:attachment":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}