<?xml version="1.0" encoding="UTF-8"?><rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
> <channel><title>Comments on: Can&#8217;t test that Singleton? Try Dependency Injection!</title> <atom:link href="http://www.androidsx.com/cant-test-that-singleton-try-dependency-injection/feed/" rel="self" type="application/rss+xml" /><link>http://www.androidsx.com/cant-test-that-singleton-try-dependency-injection/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cant-test-that-singleton-try-dependency-injection</link> <description>Android specialists</description> <lastBuildDate>Sun, 08 Jan 2012 15:41:18 +0000</lastBuildDate> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.2.1</generator> <item><title>By: Pablo Pera Mira</title><link>http://www.androidsx.com/cant-test-that-singleton-try-dependency-injection/comment-page-1/#comment-1194</link> <dc:creator>Pablo Pera Mira</dc:creator> <pubDate>Tue, 17 Aug 2010 08:34:41 +0000</pubDate> <guid
isPermaLink="false">http://www.androidsx.com/?p=60#comment-1194</guid> <description>@Bhavinkumar
The example you write is exactly what we are trying to avoid, by applying dependency injection. In its current state, you would have a hard time testing your class abc, since you can&#039;t use a fake object or a mock instead of XYZConfiguration.Let me first rewrite your example into something that compiles fine:
{code starts}
class Abc {
public void init() {
XyzConfiguration xyz = XyzConfiguration.getInstance();
xyz.configureXyz();
}
public void someMethod() {
System.out.println(&quot;Some method works fine&quot;);
}
}/** Singleton that holds the configuration for XYZ */
class XyzConfiguration {
private static XyzConfiguration XYZ_CONFIGURATION = null;
/** This class is not instantiable from outside. Use {@link #getInstance}. */
private XyzConfiguration() {
}
public static XyzConfiguration getInstance() {
if (XYZ_CONFIGURATION == null) {
XYZ_CONFIGURATION = new XyzConfiguration();
}
return XYZ_CONFIGURATION;
}
public void configureXyz() {
System.out.println(&quot;Configure XYZ&quot;);
}
}public class AbcTest {
Abc abc;@Before
public void setUp() {
abc = new Abc();
abc.init();
}
@Test
public void testSomeMethod() {
abc.someMethod();
// Assert something, to make sure it worked...
}
}
{code ends}Now, if the configuration implies using a production system, writing into a database and whatnot, this test will be slow and dangerous.To fix this, let&#039;s apply dependency injection, and this is the final result:{code begins}
class Abc {
private final XyzConfiguration xyz;
public Abc(XyzConfiguration xyz) {
this.xyz = xyz;
}public void init() {
xyz.configureXyz();
}
public void someMethod() {
System.out.println(&quot;Some method works fine&quot;);
}
}interface XyzConfiguration {
public void configureXyz();
}
/** Singleton that holds the configuration for XYZ */
class DefaultXyzConfiguration implements XyzConfiguration {
private static XyzConfiguration XYZ_CONFIGURATION = null;
/** This class is not instantiable from outside. Use {@link #getInstance}. */
private DefaultXyzConfiguration() {
}
public static XyzConfiguration getInstance() {
if (XYZ_CONFIGURATION == null) {
XYZ_CONFIGURATION = new DefaultXyzConfiguration();
}
return XYZ_CONFIGURATION;
}
@Override
public void configureXyz() {
System.out.println(&quot;Configure XYZ&quot;);
}
}public class AbcTest {
Abc abc;
@Before
public void setUp() {
abc = new Abc(new FakeXyzConfiguration());
abc.init();
}
@Test
public void testSomeMethod() {
abc.someMethod();
// Assert something, to make sure it worked...
}
class FakeXyzConfiguration implements XyzConfiguration {
@Override
public void configureXyz() {
System.out.println(&quot;Lightweight configuration, just for testing&quot;);
}
}
}
{code ends}Now you can test Abc in isolation. And, as a bonus, now your Abc class doesn&#039;t even notice about changes in the implementation of XYZ configuration. Now it is only aware of the interface.Hope it helps, and sorry that the code is not properly formatted!</description> <content:encoded><![CDATA[<p>@Bhavinkumar<br
/> The example you write is exactly what we are trying to avoid, by applying dependency injection. In its current state, you would have a hard time testing your class abc, since you can&#8217;t use a fake object or a mock instead of XYZConfiguration.</p><p>Let me first rewrite your example into something that compiles fine:<br
/> {code starts}<br
/> class Abc {<br
/> public void init() {<br
/> XyzConfiguration xyz = XyzConfiguration.getInstance();<br
/> xyz.configureXyz();<br
/> }</p><p> public void someMethod() {<br
/> System.out.println(&#8220;Some method works fine&#8221;);<br
/> }<br
/> }</p><p>/** Singleton that holds the configuration for XYZ */<br
/> class XyzConfiguration {<br
/> private static XyzConfiguration XYZ_CONFIGURATION = null;</p><p> /** This class is not instantiable from outside. Use {@link #getInstance}. */<br
/> private XyzConfiguration() {<br
/> }</p><p> public static XyzConfiguration getInstance() {<br
/> if (XYZ_CONFIGURATION == null) {<br
/> XYZ_CONFIGURATION = new XyzConfiguration();<br
/> }<br
/> return XYZ_CONFIGURATION;<br
/> }</p><p> public void configureXyz() {<br
/> System.out.println(&#8220;Configure XYZ&#8221;);<br
/> }<br
/> }</p><p>public class AbcTest {<br
/> Abc abc;</p><p> @Before<br
/> public void setUp() {<br
/> abc = new Abc();<br
/> abc.init();<br
/> }</p><p> @Test<br
/> public void testSomeMethod() {<br
/> abc.someMethod();<br
/> // Assert something, to make sure it worked&#8230;<br
/> }<br
/> }<br
/> {code ends}</p><p>Now, if the configuration implies using a production system, writing into a database and whatnot, this test will be slow and dangerous.</p><p>To fix this, let&#8217;s apply dependency injection, and this is the final result:</p><p>{code begins}<br
/> class Abc {<br
/> private final XyzConfiguration xyz;</p><p> public Abc(XyzConfiguration xyz) {<br
/> this.xyz = xyz;<br
/> }</p><p> public void init() {<br
/> xyz.configureXyz();<br
/> }</p><p> public void someMethod() {<br
/> System.out.println(&#8220;Some method works fine&#8221;);<br
/> }<br
/> }</p><p>interface XyzConfiguration {<br
/> public void configureXyz();<br
/> }</p><p>/** Singleton that holds the configuration for XYZ */<br
/> class DefaultXyzConfiguration implements XyzConfiguration {<br
/> private static XyzConfiguration XYZ_CONFIGURATION = null;</p><p> /** This class is not instantiable from outside. Use {@link #getInstance}. */<br
/> private DefaultXyzConfiguration() {<br
/> }</p><p> public static XyzConfiguration getInstance() {<br
/> if (XYZ_CONFIGURATION == null) {<br
/> XYZ_CONFIGURATION = new DefaultXyzConfiguration();<br
/> }<br
/> return XYZ_CONFIGURATION;<br
/> }</p><p> @Override<br
/> public void configureXyz() {<br
/> System.out.println(&#8220;Configure XYZ&#8221;);<br
/> }<br
/> }</p><p>public class AbcTest {<br
/> Abc abc;</p><p> @Before<br
/> public void setUp() {<br
/> abc = new Abc(new FakeXyzConfiguration());<br
/> abc.init();<br
/> }</p><p> @Test<br
/> public void testSomeMethod() {<br
/> abc.someMethod();<br
/> // Assert something, to make sure it worked&#8230;<br
/> }</p><p> class FakeXyzConfiguration implements XyzConfiguration {<br
/> @Override<br
/> public void configureXyz() {<br
/> System.out.println(&#8220;Lightweight configuration, just for testing&#8221;);<br
/> }<br
/> }<br
/> }<br
/> {code ends}</p><p>Now you can test Abc in isolation. And, as a bonus, now your Abc class doesn&#8217;t even notice about changes in the implementation of XYZ configuration. Now it is only aware of the interface.</p><p>Hope it helps, and sorry that the code is not properly formatted!</p> ]]></content:encoded> </item> <item><title>By: Bhavinkumar</title><link>http://www.androidsx.com/cant-test-that-singleton-try-dependency-injection/comment-page-1/#comment-1191</link> <dc:creator>Bhavinkumar</dc:creator> <pubDate>Tue, 17 Aug 2010 03:54:47 +0000</pubDate> <guid
isPermaLink="false">http://www.androidsx.com/?p=60#comment-1191</guid> <description>hi,I am learning mockito and unittesting.I am writing testcase for a Class , which Uses singleton  class instance inside one method. The method that gives the instance is &quot;Static&quot;.for ex:public class abc{public init(){
XYZConfiguration xyz = XYZConfiguration.getInstance();
}}// This class is initialized with SPRING
// Singleton Class
public class XYZConfiguration {private static XYZConfiguration = null;public static getInstance() {
if(XYZConfiguration ==null)
throw new exception();
else
return XYZConfiguration;
}}can you suggest me any idea, how to use mock and spy on this ??Thanks,
Bhavin</description> <content:encoded><![CDATA[<p>hi,</p><p>I am learning mockito and unittesting.</p><p>I am writing testcase for a Class , which Uses singleton  class instance inside one method. The method that gives the instance is &#8220;Static&#8221;.</p><p>for ex:</p><p>public class abc{</p><p>public init(){<br
/> XYZConfiguration xyz = XYZConfiguration.getInstance();<br
/> }</p><p>}</p><p>// This class is initialized with SPRING<br
/> // Singleton Class<br
/> public class XYZConfiguration {</p><p> private static XYZConfiguration = null;</p><p> public static getInstance() {</p><p> if(XYZConfiguration ==null)<br
/> throw new exception();<br
/> else<br
/> return XYZConfiguration;<br
/> }</p><p>}</p><p>can you suggest me any idea, how to use mock and spy on this ??</p><p>Thanks,<br
/> Bhavin</p> ]]></content:encoded> </item> <item><title>By: Pablo Pera Mira</title><link>http://www.androidsx.com/cant-test-that-singleton-try-dependency-injection/comment-page-1/#comment-685</link> <dc:creator>Pablo Pera Mira</dc:creator> <pubDate>Wed, 07 Jul 2010 21:47:41 +0000</pubDate> <guid
isPermaLink="false">http://www.androidsx.com/?p=60#comment-685</guid> <description>But most likely those 20 classes only need access to specific objects/services that the server provides. So you would inject only what they really need (following the Law of Demeter). This way, they are not even aware of the server class, which might come in handy in a future refactoring.Still, sometimes there are trade-offs to make. What can easily happen with dependency injection is that your constructors end up having too many arguments. Another problem is that some classes are just forwarding objects that they don&#039;t even need to others.To alleviate this, you can &quot;start the dependency injection later&quot;: let a selected group of central classes get the server instance, and inject from there.Not sure I made my point. It&#039;s sort of difficult to explain without an example and with my limited literary skills :)</description> <content:encoded><![CDATA[<p>But most likely those 20 classes only need access to specific objects/services that the server provides. So you would inject only what they really need (following the Law of Demeter). This way, they are not even aware of the server class, which might come in handy in a future refactoring.</p><p>Still, sometimes there are trade-offs to make. What can easily happen with dependency injection is that your constructors end up having too many arguments. Another problem is that some classes are just forwarding objects that they don&#8217;t even need to others.</p><p>To alleviate this, you can &#8220;start the dependency injection later&#8221;: let a selected group of central classes get the server instance, and inject from there.</p><p>Not sure I made my point. It&#8217;s sort of difficult to explain without an example and with my limited literary skills <img
src='http://www.androidsx.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> ]]></content:encoded> </item> <item><title>By: david</title><link>http://www.androidsx.com/cant-test-that-singleton-try-dependency-injection/comment-page-1/#comment-684</link> <dc:creator>david</dc:creator> <pubDate>Wed, 07 Jul 2010 19:59:25 +0000</pubDate> <guid
isPermaLink="false">http://www.androidsx.com/?p=60#comment-684</guid> <description>Dependency injection to mock singleton ?
A Very bypassing solution.
If the singleton is central and you need the singleton in 20 classes of your application, you will add the dependency in the 20 classes ?
You can but you make your design heavier.</description> <content:encoded><![CDATA[<p>Dependency injection to mock singleton ?<br
/> A Very bypassing solution.<br
/> If the singleton is central and you need the singleton in 20 classes of your application, you will add the dependency in the 20 classes ?<br
/> You can but you make your design heavier.</p> ]]></content:encoded> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 1/8 queries in 0.040 seconds using disk: basic
Object Caching 284/287 objects using disk: basic

Served from: www.androidsx.com @ 2012-02-05 14:30:06 -->
