tag:blogger.com,1999:blog-68411480023478896872024-03-14T01:32:38.292-04:00Active-Active ConfigurationRyan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.comBlogger31125tag:blogger.com,1999:blog-6841148002347889687.post-29597915231478876122018-04-10T18:57:00.000-04:002018-04-10T19:09:51.256-04:00Phone Dump: 2018-04-10<p>Here is a list of things that I've been holding onto on my phone. I finally got around to reading them today and wanted to share:
<a name='more'></a>
<ul>
<li><a href="http://inspirobot.me/">InspiroBot</a> – What if you could get custom-generated motivational posters? This site has an machine-learning implementation with everything you need.</li>
<li><a href="http://hilite.me/">hilite.me</a> – Instead of adding a JavaScript/CSS package to your pages when you want to display code snippets, use this application to get a nicely-CSS-ified version of your code.</li>
<li><a href="https://medium.com/@codepo8/what-comes-after-senior-developer-78b9956a9c66">What Comes After Senior Developer</a> – Some ideas for what to do when being a front-line developer is no longer fun at your company and other ideas to help prevent burn-out due to bureaucracy/turnover.</li>
<li><a href="http://netflix.github.io/">Open Source Software from Netflix</a> – What it says on the tin. These are the tools/frameworks which Netflix is providing back to the community through Github.</li>
<li>Twitter kind of made a dog's breakfast out of this thread providing some receipts about the draw-backs of open-plan offices. Alina Manda lays out some references to papers that she found in her reading of Susan Cain's "Quiet":
<ul>
<li><a href="https://twitter.com/comp2sch/status/982627553658724353">Initial tweet</a></li>
<li><a href="https://twitter.com/comp2sch/status/982630673277218816">References #1 and #2</a></li>
<li><a href="https://twitter.com/comp2sch/status/982631009744285697">References #3 and #4</a></li>
<li><a href="https://twitter.com/comp2sch/status/982631441107443712">References #5 and #6</a></li>
<li><a href="https://twitter.com/comp2sch/status/982631696695746560">References #7 and #8</a></li>
</ul>
</li>
<li><a href="https://blog.safia.rocks/">Safia Abdalla</a> has been doing some code-reading while finishing up her degree. I just happened to run across her breakdown of git internals and thought that she had a pretty cool approach:
<ol>
<li><a href="https://blog.safia.rocks/post/171448973555/getting-into-git-init">Getting into git init</a></li>
<li><a href="https://blog.safia.rocks/post/171558325240/whats-inside-the-git-directory">What's inside the .git directory?</a></li>
<li><a href="https://blog.safia.rocks/post/171624930481/whats-in-a-git-config">What's in a git config?</a></li>
<li><a href="https://blog.safia.rocks/post/171693534895/trying-to-figure-out-how-git-status-works-a-saga">Trying to figure out how git-status works: a saga</a></li>
<li><a href="https://blog.safia.rocks/post/171796245560/how-does-git-store-working-tree-state">How does Git store working tree state?</a></li>
<li><a href="https://blog.safia.rocks/post/171866471130/how-does-git-know-if-you-have-uncommitted-changes">How does Git know if you have uncommitted changes in the working tree? (Part I)</a></li>
<li><a href="https://blog.safia.rocks/post/171932025970/whats-inside-the-gitobjects-directory">What's inside the `.git/objects` directory?</a></li>
<li><a href="https://blog.safia.rocks/post/172032754710/reading-code-late-at-night-and-realizing-that-its">Reading code late at night and realizing that it's not a good idea</a> – This one's about <tt>add_head_to_pending</tt> and the <tt>object</tt> struct.</li>
<li><a href="https://blog.safia.rocks/post/172170673860/learning-more-about-how-commits-are-represented-in">Learning more about how commits are represented in Git</a></li>
<li><a href="https://blog.safia.rocks/post/172273926295/a-complete-story-of-what-happens-when-you-run-git">A complete story of what happens when you run `git commit`</a></li>
<li><a href="https://blog.safia.rocks/post/172344263235/how-does-git-add-work-under-the-hood">How does `git add` work under the hood?</a></li>
<li><a href="https://blog.safia.rocks/post/171381157060/looking-into-ls"><i>bonus</i> – Looking into ls</a></li>
<li><a href="https://blog.safia.rocks/post/171200937595/what-happens-when-you-run-sudo"><i>bonus</i> – What happens when you run sudo?</a></li>
</ol>
</li>
</ul>
</p>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-50367142969777018992012-07-11T09:03:00.000-04:002018-04-10T16:12:15.462-04:00Executing JUnit Runners Outside Of JUnit<p>I received a comment on one of my previous <a href="http://active-active.blogspot.com/2011/01/testing-toolbelt-springjunit4classrunne.html">posts</a> asking how to run a test class using <code>SpringJUnit4ClassRunner</code> from normal application code (i.e. within a <code>main</code> method). I'll admit, I didn't know how to do this, but my interest was piqued.</p>
<a name='more'></a></ br>
<p>I ran off to an existing test class I had laying around. Within a few minutes, I had a working prototype:
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">static</span> <span style="color: #902000">void</span> <span style="color: #06287e">main</span><span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">final</span> String<span style="color: #666666">[]</span> args<span style="color: #666666">)</span> <span style="color: #007020; font-weight: bold">throws</span> Exception <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">final</span> Class testClass <span style="color: #666666">=</span> Class<span style="color: #666666">.</span><span style="color: #4070a0">forName</span><span style="color: #666666">(</span>args<span style="color: #666666">[</span><span style="color: #40a070">0</span><span style="color: #666666">]);</span>
<span style="color: #007020; font-weight: bold">final</span> Runner r <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> SpringJUnit4ClassRunner<span style="color: #666666">(</span>testClass<span style="color: #666666">);</span>
<span style="color: #007020; font-weight: bold">final</span> RunNotifier n <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> RunNotifier<span style="color: #666666">();</span>
<span style="color: #007020; font-weight: bold">final</span> RunListener l <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> RunListener<span style="color: #666666">()</span> <span style="color: #666666">{</span>
<span style="color: #555555; font-weight: bold">@Override</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">testRunStarted</span><span style="color: #666666">(</span>Description d<span style="color: #666666">)</span> <span style="color: #666666">{</span>
System<span style="color: #666666">.</span><span style="color: #4070a0">out</span><span style="color: #666666">.</span><span style="color: #4070a0">println</span><span style="color: #666666">(</span><span style="color: #4070a0">"Tests are starting"</span><span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@Override</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">testIgnored</span><span style="color: #666666">(</span>Description d<span style="color: #666666">)</span> <span style="color: #666666">{</span>
System<span style="color: #666666">.</span><span style="color: #4070a0">out</span><span style="color: #666666">.</span><span style="color: #4070a0">println</span><span style="color: #666666">(</span><span style="color: #4070a0">"Test is ignored"</span><span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@Override</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">testStarted</span><span style="color: #666666">(</span>Description d<span style="color: #666666">)</span> <span style="color: #666666">{</span>
System<span style="color: #666666">.</span><span style="color: #4070a0">out</span><span style="color: #666666">.</span><span style="color: #4070a0">println</span><span style="color: #666666">(</span><span style="color: #4070a0">"Starting a test"</span><span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@Override</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">testFailure</span><span style="color: #666666">(</span>Failure f<span style="color: #666666">)</span> <span style="color: #666666">{</span>
System<span style="color: #666666">.</span><span style="color: #4070a0">out</span><span style="color: #666666">.</span><span style="color: #4070a0">println</span><span style="color: #666666">(</span><span style="color: #4070a0">"WOAH! Test failed"</span><span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@Override</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">testAssumptionFailure</span><span style="color: #666666">(</span>Failure f<span style="color: #666666">)</span> <span style="color: #666666">{</span>
System<span style="color: #666666">.</span><span style="color: #4070a0">out</span><span style="color: #666666">.</span><span style="color: #4070a0">println</span><span style="color: #666666">(</span><span style="color: #4070a0">"WOAH! Assertion failed"</span><span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@Override</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">testFinished</span><span style="color: #666666">(</span>Description d<span style="color: #666666">)</span> <span style="color: #666666">{</span>
System<span style="color: #666666">.</span><span style="color: #4070a0">out</span><span style="color: #666666">.</span><span style="color: #4070a0">println</span><span style="color: #666666">(</span><span style="color: #4070a0">"Test has finished"</span><span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@Override</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">testRunFinished</span><span style="color: #666666">(</span>Result r<span style="color: #666666">)</span> <span style="color: #666666">{</span>
System<span style="color: #666666">.</span><span style="color: #4070a0">out</span><span style="color: #666666">.</span><span style="color: #4070a0">println</span><span style="color: #666666">(</span><span style="color: #4070a0">"Tests have finished"</span><span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #666666">}</span>
n<span style="color: #666666">.</span><span style="color: #4070a0">addListener</span><span style="color: #666666">(</span>l<span style="color: #666666">);</span>
r<span style="color: #666666">.</span><span style="color: #4070a0">run</span><span style="color: #666666">(</span>n<span style="color: #666666">);</span>
<span style="color: #666666">}</span>
</pre></div></p>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-53504130393669754522012-01-24T15:00:00.001-05:002012-01-24T15:01:42.071-05:00Making a Move ForwardToday I made some commitments to present some "lightning-talks" on .NET topics for my local .NET user group. I may be giving some discussions on C# basics, HTML5 topics, LESS(CSS), and JavaScript. Like many others who are working in the presentation/evangelism circuit, I feel that this will help force me into showing off some talents that I do have and learning some things that I currently don't know.<br />
<br />
Follow the Evansville .NET User Group <a href="www.evansvillednug.com">homepage</a> for more details.Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-52049927014062697512011-10-28T11:41:00.000-04:002018-04-10T18:16:49.932-04:00Java Problem: Generic Inheritance and Calling GetMethod().getReturnType()<p>In my current project, I have classes which are modeled like the following. At some point, a method like <code>getReturnTypeForGetId()</code> is called on classes <code>A</code> and <code>B</code>. Calling the method with <code>A</code> returns <code>Integer</code> as expected, but <code>B</code> returns <code>Serializable</code>.</p>
<p>What am I missing here? Am I getting bitten by some heinous erasure thing, or am I just missing out on some sort of generic context-clobbering?</p>
<p><b>EDIT:</b> Adding an over-ridden <code>getId()</code> method to <code>B</code> fixes the problem, but I would still like to understand what I am running into.</p>
<p>I've also asked this question on <a href="http://stackoverflow.com/questions/7931629/generic-inheritance-and-calling-getmethod-getreturntype">stackoverflow.</a></p>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">java.io.Serializable</span><span style="color: #666666">;</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">WeirdTester</span> <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">static</span> <span style="color: #007020; font-weight: bold">interface</span> <span style="color: #0e84b5; font-weight: bold">Identifiable</span><span style="color: #666666">&</span>lt<span style="color: #666666">;</span>T <span style="color: #007020; font-weight: bold">extends</span> Serializable<span style="color: #666666">></span> <span style="color: #666666">{</span>
T <span style="color: #06287e">getId</span><span style="color: #666666">();</span>
<span style="color: #902000">void</span> <span style="color: #06287e">setId</span><span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">final</span> T id<span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #007020; font-weight: bold">static</span> <span style="color: #007020; font-weight: bold">abstract</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">BaseEntity</span><span style="color: #666666">&</span>lt<span style="color: #666666">;</span>T <span style="color: #007020; font-weight: bold">extends</span> Serializable<span style="color: #666666">></span> <span style="color: #007020; font-weight: bold">implements</span> Identifiable<span style="color: #666666">&</span>lt<span style="color: #666666">;</span>T<span style="color: #666666">></span> <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">private</span> T id<span style="color: #666666">;</span>
<span style="color: #007020; font-weight: bold">public</span> T <span style="color: #06287e">getId</span><span style="color: #666666">()</span> <span style="color: #666666">{</span> <span style="color: #007020; font-weight: bold">return</span> id<span style="color: #666666">;</span> <span style="color: #666666">}</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">setId</span><span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">final</span> T id<span style="color: #666666">)</span> <span style="color: #666666">{</span> <span style="color: #007020; font-weight: bold">this</span><span style="color: #666666">.</span><span style="color: #4070a0">id</span> <span style="color: #666666">=</span> id<span style="color: #666666">;</span> <span style="color: #666666">}</span>
<span style="color: #666666">}</span>
<span style="color: #007020; font-weight: bold">static</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">A</span> <span style="color: #007020; font-weight: bold">implements</span> Identifiable<span style="color: #666666">&</span>lt<span style="color: #666666">;</span>Integer<span style="color: #666666">></span> <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">private</span> Integer id<span style="color: #666666">;</span>
<span style="color: #007020; font-weight: bold">public</span> Integer <span style="color: #06287e">getId</span><span style="color: #666666">()</span> <span style="color: #666666">{</span> <span style="color: #007020; font-weight: bold">return</span> id<span style="color: #666666">;</span> <span style="color: #666666">}</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">setId</span><span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">final</span> Integer id<span style="color: #666666">)</span> <span style="color: #666666">{</span> <span style="color: #007020; font-weight: bold">this</span><span style="color: #666666">.</span><span style="color: #4070a0">id</span> <span style="color: #666666">=</span> id<span style="color: #666666">;</span> <span style="color: #666666">}</span>
<span style="color: #666666">}</span>
<span style="color: #007020; font-weight: bold">static</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">B</span> <span style="color: #007020; font-weight: bold">extends</span> BaseEntity<span style="color: #666666">&</span>lt<span style="color: #666666">;</span>Integer<span style="color: #666666">></span> <span style="color: #666666">{}</span>
<span style="color: #555555; font-weight: bold">@SuppressWarnings</span><span style="color: #666666">(</span><span style="color: #4070a0">"unchecked"</span><span style="color: #666666">)</span>
<span style="color: #007020; font-weight: bold">private</span> <span style="color: #007020; font-weight: bold">static</span> <span style="color: #666666">&</span>lt<span style="color: #666666">;</span>T <span style="color: #007020; font-weight: bold">extends</span> Serializable<span style="color: #666666">,</span> Q <span style="color: #007020; font-weight: bold">extends</span> Identifiable<span style="color: #666666">&</span>lt<span style="color: #666666">;</span>T<span style="color: #666666">>></span> Class<span style="color: #666666">&</span>lt<span style="color: #666666">;</span>T<span style="color: #666666">></span> getReturnTypeForGetId<span style="color: #666666">(</span>
<span style="color: #007020; font-weight: bold">final</span> Class<span style="color: #666666">&</span>lt<span style="color: #666666">;</span>Q<span style="color: #666666">></span> clazz<span style="color: #666666">)</span> <span style="color: #007020; font-weight: bold">throws</span> Exception <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #666666">(</span>Class<span style="color: #666666">&</span>lt<span style="color: #666666">;</span>T<span style="color: #666666">>)</span> clazz<span style="color: #666666">.</span><span style="color: #4070a0">getMethod</span><span style="color: #666666">(</span><span style="color: #4070a0">"getId"</span><span style="color: #666666">,</span> <span style="color: #666666">(</span>Class<span style="color: #666666">[])</span><span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">).</span><span style="color: #4070a0">getReturnType</span><span style="color: #666666">();</span>
<span style="color: #666666">}</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">static</span> <span style="color: #902000">void</span> <span style="color: #06287e">main</span><span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">final</span> String<span style="color: #666666">[]</span> args<span style="color: #666666">)</span> <span style="color: #007020; font-weight: bold">throws</span> Exception <span style="color: #666666">{</span>
System<span style="color: #666666">.</span><span style="color: #4070a0">out</span><span style="color: #666666">.</span><span style="color: #4070a0">println</span><span style="color: #666666">(</span>getReturnTypeForGetId<span style="color: #666666">(</span>A<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">));</span>
<span style="color: #60a0b0; font-style: italic">// CONSOLE: "class java.lang.Integer"</span>
System<span style="color: #666666">.</span><span style="color: #4070a0">out</span><span style="color: #666666">.</span><span style="color: #4070a0">println</span><span style="color: #666666">(</span>getReturnTypeForGetId<span style="color: #666666">(</span>B<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">));</span>
<span style="color: #60a0b0; font-style: italic">// CONSOLE: "interface java.io.Serializable"</span>
<span style="color: #666666">}</span>
<span style="color: #666666">}</span>
</pre></div>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-62053115861340831992011-04-24T21:00:00.000-04:002011-04-24T21:00:18.729-04:00Quick Hint: Command-line tools for MonoDevelop on Mac OS XIn doing some investigation for doing contract-first development for web services on .NET, I ran into the <tt>wsdl</tt> command-line tool. Unfortunately, I was unable to find its equivalent in the MonoDevelop IDE. I finally did some digging around in the terminal and found the MonoDevelop command-line tools at: <tt>/Library/Frameworks/Mono.framework</tt> or <tt>/Library/Frameworks/Mono.framework/Versions/current/bin</tt>.Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-61793619772433871542011-04-08T00:07:00.000-04:002018-04-10T18:14:33.301-04:00Using MonoDevelop to Create an ASP.NET Web Service<p><b>NOTE</b>: instructions below are for MonoDevelop 2.6 Beta 2 - built on 2011-04-06 03:37:58+0000</p>
<h2>Getting Started</h2>
<p>Create a new ASP.NET Web Application in MonoDevelop:
<ol>
<li>From the menu, select: <i>File → New → Solution…</i></li>
<li>Expand <i>C#</i>.</li>
<li>Select <i>ASP.NET → Web Application</i>.</li>
<li>Enter a name for the ASP.NET project that will be created in the solution in <i>Name:</i>.</li>
<li>Change the root location for the solution in <i>Location:</i>, if desired.</li>
<li>Change the name of the root solution in <i>Solution Name:</i>, if desired.</li>
</ol></p>
<h2>The Results – I</h2>
<p>What you have after executing the new ASP.NET Web Application project wizard is a solution containing one ASP.NET Web Application project. In the default project view in MonoDevelop, you'll find the following items:
<ul>
<li><tt>Default.aspx</tt> – This is the default web form rendered and presented in the browser when <tt>http://<server>:<port>/</tt> is accessed.
<ul>
<li><tt>Default.aspx.cs</tt> – This C# file contains the developer-created common code and event handlers which can be used to affect the processing of the form.</li>
<li><tt>Default.aspx.designer.cs</tt> – This C# file contains the IDE-generated code for the page.</li>
</ul>
Both of the above files contain partial class definitions which are compiled together into a single code-behind class at runtime.</li>
<li><tt>Global.asax</tt> – This file contains the basic information which is available to the entire application.</li>
<ul>
<li><tt>Global.asax.cs</tt> – This C# file contains methods and event handlers for the entire application. These include event handlers for: application initialization, application termination, session handling, error handling, and request handling.</li>
</ul>
<li><tt>web.config</tt> – This file contains the primary configuration for the application when deployed to a server. A secondary set of configuration options can be found in the server's <tt>Machine.config</tt> file.</li>
</ul></p>
<p>If you go out to the location where you created the solution/project, you will also find a few other files:
<ul>
<li><tt>/<solution name>/<solution name>.sln</tt> – This file contains configuration information for the entire "workspace" of projects.</li>
<li><tt>/<solution name>/<solution name>.userprefs</tt> – This file is generated by MonoDevelop and contains information specific to the user of the MonoDevelop application. The consensus is that this file should not be included in source-control.</li>
<li><tt>/<solution name>/<project name>/<project name>.csproj</tt> – This file contains configuration information for the particular project.</li>
<li><tt>/<solution name>/<project name>/<project name>.pidb</tt> – This binary file contains meta-data generated by MonoDevelop. The consensus is also that this file should not be included in source-control.</li>
</ul></p>
<h2>Setting Up the Web Service</h2>
<p>Since I'm only really interested in exposing a web service using this project, I felt that I really don't need the <tt>Default.aspx.*</tt> or <tt>Global.asax.*</tt> files as they are currently not doing anything for the project. I deleted all five of the files.</p>
<p>Create a new ASP.NET Web Service file in MonoDevelop:
<ol>
<li>In the Solution pad, right-click your project and select: <i>Add → New File…</i></li>
<li>Select <i>ASP.NET → Web Service</i>.</li>
<li>Enter a name for the file that will be created in the project in <i>Name:</i>.</li>
</ol></p>
<h2>The Results – II</h2>
<p>After the ASP.NET web service wizard has completed, you'll find a new <tt>asmx</tt> file in your project. This file will contain the basic <tt>WebService</tt> directive, some using statements (<tt>System</tt> and <tt>System.Web.Services</tt>), a namespace, and a class definition.</p>
<h2>Exposing a Method in the Web Service</h2>
<p>Next, you'll want to create a method that you want to expose as a method on your web service. Add the <tt>WebMethod</tt> attribute to it. Your <tt>asmx</tt> file will now look something like this:</p>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">%@ WebService Language=<span style="color: #4070a0">"C#"</span> Class=<span style="color: #4070a0">"service.Service"</span> %>
<span style="color: #007020; font-weight: bold">using</span> <span style="color: #0e84b5; font-weight: bold">System</span>;
<span style="color: #007020; font-weight: bold">using</span> <span style="color: #0e84b5; font-weight: bold">System.Web.Services</span>;
<span style="color: #007020; font-weight: bold">namespace</span> <span style="color: #0e84b5; font-weight: bold">service</span> {
<span style="color: #007020; font-weight: bold">internal</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">Service</span> {
<span style="color: #4070a0"> [WebMethod]</span>
<span style="color: #007020; font-weight: bold">public</span> String <span style="color: #06287e">doIt</span>(String arg) {
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #4070a0">""</span>;
}
}
}
</pre></div>
<p>When you run this project, you can view a simple front-end for the service at <tt>http://localhost:8080/<web service file name>.asmx</tt>. This web form is created at runtime by the ASP.NET container.</p>
<h2>What? No code-behind?</h2>
<p>While it is normally a good practice to separate a view from the code which contains its logic, as in an <tt>aspx</tt> file, there is really no reason to do so in an <tt>asmx</tt> file as there is no visual component which must be separated from the code.</p>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com5tag:blogger.com,1999:blog-6841148002347889687.post-61348911922816261282011-04-07T10:58:00.000-04:002018-04-10T18:12:18.490-04:00Getting Started with .NET on the Mac<p> I'm setting out to learn .NET and get some experience creating a non-trivial project. Microsoft does provide Express <i>(free, Windows-only)</i> editions of the Visual Studio application in a few flavors as well as basic version of IIS with ASP.NET and SQL Server. But, since my current personal development environment is a MacBook Pro (OSX 10.6.7), getting started with development on .NET can actually cost money <i>(mostly due to the Windows tax)</i>. The primary development tool for .NET developers on non-Windows systems seems to be <a href="https://www.mono-project.com">Mono</a> with <a href="http://www.monodevelop.com">MonoDevelop</a>.</p>
<p>The latest stable release of Mono <i>(2.10.1)</i> supports much of the functionality of the .NET 4.0 platform and some portions of Microsoft's extended .NET eco-system: <i>F#, IronRuby, IronPython, ASP.NET MVC(1, 2, and portions of 3)</i>.</p>
<p>The latest beta build of MonoDevelop <i>(2.6 beta 2)</i> provides a lot of support for developing applications using C# and the rest of the CLR.</p>
<p>I'll be using these in the coming months to do some experiments in the creation of a blogging engine in .NET. As part of proving that I can work in the .NET world. You can see the results of my experiments on my <a href="https://github.com/wimplash/scratch-NET/tree/master/wbe">github</a> page.</p>
<p>Mono also provides two other interesting projects:
<ul>
<li><a href="http://mono-android.net">Mono for Android</a> -- run .NET applications on Android devices.</li>
<li><a href="http://monotouch.net">MonoTouch</a> -- run .NET applications on iOS devices (iPhone, iTouch, iPad).</li>
</ul></p>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-48315202140028814952011-04-01T00:37:00.001-04:002018-04-10T18:10:12.078-04:00Testing Toolbelt: Testing non-xml attributes of responses in SoapUI<p>I spend a large part of my time developing web services, so I spend a lot of my time testing web services. One of the major tools I have in my toolbelt for automating web service tests is <a href="http://www.soapui.org">SoapUI</a>. SoapUI does a lot of things, and even does a lot of things which I don't need, but it does the things I need very well. Today, I was trying to set up some testing for the security on my current project. As I was setting up the test request and pointing SoapUI at the appropriate endpoints with invalid http basic authorization credentials, I realized that there was no straight forward way to assert that the http response code was 401 (unauthorized) or 403 (forbidden). I did some digging, and found that you could create a Script Assertion (using Groovy) in the SOAP Test Step and use the pre-defined variable, <tt>messageExchange</tt>, to examine contents and statistics for the test step.</p>
<h2>Asserting that a SOAP request with no credentials was responded to with a 401</h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020; font-weight: bold">assert</span> messageExchange<span style="color: #666666">.</span><span style="color: #4070a0">getResponseStatusCode</span><span style="color: #666666">()</span> <span style="color: #666666">==</span> <span style="color: #40a070">401</span>
</pre></div>
<h2>Asserting that a SOAP request with invalid credentials was responded to with a 403</h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020; font-weight: bold">assert</span> messageExchange<span style="color: #666666">.</span><span style="color: #4070a0">getResponseStatusCode</span><span style="color: #666666">()</span> <span style="color: #666666">==</span> <span style="color: #40a070">403</span>
</pre></div>
<p>The Script Assertion also has access to two other pre-defined variables: <tt>context</tt> and <tt>log</tt>. <tt>context</tt> contains methods which allow you to examine the request and response programmatically and <tt>log</tt>, well I haven't had to use yet. These are posts for another day.</p>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-3687218402618611652011-04-01T00:06:00.000-04:002018-04-10T18:08:49.929-04:00Maven Note: Securing a temporary Jetty instance in the jetty-maven-plugin<p>One of my tasks for the current iteration was to add security constraints to the J2EE web service that we are currently developing. This is the easy part. Simply define the appropriate <tt>security-constraint</tt>, <tt>login-config</tt>, and <tt>security-role</tt> elements in the project's <tt>web.xml</tt>.</p>
<h2><tt>web.xml</tt></h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #062873; font-weight: bold"><web-app</span> <span style="color: #4070a0">xmlns="http://java.sun.com/xml/ns/j2ee"</span>
<span style="color: #4070a0">xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span>
<span style="color: #4070a0">xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><display-name></span>...<span style="color: #062873; font-weight: bold"></display-name></span>
<span style="color: #062873; font-weight: bold"><servlet></span>...<span style="color: #062873; font-weight: bold"></servlet></span>
<span style="color: #062873; font-weight: bold"><servlet-mapping></span>...<span style="color: #062873; font-weight: bold"></servlet-mapping></span>
<span style="color: #062873; font-weight: bold"><security-constraint></span>
<span style="color: #062873; font-weight: bold"><display-name></span>deny unauthorized users<span style="color: #062873; font-weight: bold"></display-name></span>
<span style="color: #062873; font-weight: bold"><web-resource-collection></span>
<span style="color: #062873; font-weight: bold"><web-resource-name></span>global<span style="color: #062873; font-weight: bold"></web-resource-name></span>
<span style="color: #062873; font-weight: bold"><url-pattern></span>/<span style="color: #062873; font-weight: bold"></url-pattern></span>
<span style="color: #062873; font-weight: bold"><url-pattern></span>/*<span style="color: #062873; font-weight: bold"></url-pattern></span>
<span style="color: #062873; font-weight: bold"></web-resource-collection></span>
<span style="color: #062873; font-weight: bold"><auth-constraint></span>
<span style="color: #062873; font-weight: bold"><role-name></span>AUTHORIZED_USER<span style="color: #062873; font-weight: bold"></role-name></span>
<span style="color: #062873; font-weight: bold"></auth-constraint></span>
<span style="color: #062873; font-weight: bold"><user-data-constraint></span>
<span style="color: #60a0b0; font-style: italic"><!-- All access to this area will be SSL protected --></span>
<span style="color: #062873; font-weight: bold"><transport-guarantee></span>CONFIDENTIAL<span style="color: #062873; font-weight: bold"></transport-guarantee></span>
<span style="color: #062873; font-weight: bold"></user-data-constraint></span>
<span style="color: #062873; font-weight: bold"></security-constraint></span>
<span style="color: #062873; font-weight: bold"><login-config></span>
<span style="color: #062873; font-weight: bold"><auth-method></span>BASIC<span style="color: #062873; font-weight: bold"></auth-method></span>
<span style="color: #062873; font-weight: bold"><realm-name></span>APP<span style="color: #062873; font-weight: bold"></realm-name></span>
<span style="color: #062873; font-weight: bold"></login-config></span>
<span style="color: #062873; font-weight: bold"><security-role></span>
<span style="color: #062873; font-weight: bold"><description></span>authorized user for application<span style="color: #062873; font-weight: bold"></description></span>
<span style="color: #062873; font-weight: bold"><role-name></span>AUTHORIZED_USER<span style="color: #062873; font-weight: bold"></role-name></span>
<span style="color: #062873; font-weight: bold"></security-role></span>
<span style="color: #062873; font-weight: bold"></web-app></span>
</pre></div>
<p>From the above, you can see that I defined an expected role, <tt>AUTHORIZED_USER</tt>, an expected realm for http basic authentication, <tt>APP</tt>, and a set of resources, <tt>/</tt> and <tt>/*</tt>, which can only be accessed through SSL by a user who is a member of the <tt>AUTHORIZED_USER</tt> role. This is the easy part and should work for most application servers which are worth their salt.</p>
<h1>Enter <tt>jetty-maven-plugin</tt></h1>
<p>This project is already using the jetty-maven-plugin to run a test instance of the application. I thought it would be a good idea to make sure that the security on the localhost instance for testing would work in the same manner as the WebSphere server to which the application is to be deployed. This would help me to ensure that I, as a lazy programmer, would not have to change the functional tests (SoapUI) between localhost and dev.</p>
<p>By default, the jetty instance created by executing <tt>mvn jetty:run-war</tt> does not include a user realm for defining users and groups, a login service for handling attempted logins, or even the capability for handling SSL connections. In order to bring these components into the localhost instance, I had to make some changes to the configuration of my project's <tt>jetty-maven-plugin</tt>. First, the changes for enabling the user realm and login service.</p>
<h2><tt>pom.xml</tt> (version 1)</h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #062873; font-weight: bold"><project</span> <span style="color: #4070a0">xmlns="http://maven.apache.org/POM/4.0.0"</span>
<span>...</span>
<span><build</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><plugins></span>
...
<span style="color: #062873; font-weight: bold"><plugin></span>
<span style="color: #062873; font-weight: bold"><groupId></span>org.mortbay.jetty<span style="color: #062873; font-weight: bold"></groupId></span>
<span style="color: #062873; font-weight: bold"><artifactId></span>jetty-maven-plugin<span style="color: #062873; font-weight: bold"></artifactId></span>
<span style="color: #062873; font-weight: bold"><version></span>7.3.0.v20110203<span style="color: #062873; font-weight: bold"></version></span>
<span style="color: #062873; font-weight: bold"><configuration></span>
...
<span style="color: #062873; font-weight: bold"><userRealms></span>
<span style="color: #062873; font-weight: bold"><userRealm</span> <span style="color: #4070a0">implementation="org.mortbay.jetty.security.HashUserRealm"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><name></span>APP<span style="color: #062873; font-weight: bold"></name></span>
<span style="color: #062873; font-weight: bold"><config></span>${project.build.directory}/test-classes/jetty-users.properties<span style="color: #062873; font-weight: bold"></config></span>
<span style="color: #062873; font-weight: bold"></userRealm></span>
<span style="color: #062873; font-weight: bold"></userRealms></span>
<span style="color: #062873; font-weight: bold"><loginServices></span>
<span style="color: #062873; font-weight: bold"><loginService</span> <span style="color: #4070a0">implementation="org.eclipse.jetty.security.HashLoginService"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><name></span>APP<span style="color: #062873; font-weight: bold"></name></span>
<span style="color: #062873; font-weight: bold"><config></span>${project.build.directory}/test-classes/jetty-users.properties<span style="color: #062873; font-weight: bold"></config></span>
<span style="color: #062873; font-weight: bold"></loginService></span>
<span style="color: #062873; font-weight: bold"></loginServices></span>
<span style="color: #062873; font-weight: bold"></configuration></span>
<span style="color: #062873; font-weight: bold"></plugin></span>
...
<span style="color: #062873; font-weight: bold"></plugins></span>
...
<span style="color: #062873; font-weight: bold"></build></span>
...
<span style="color: #062873; font-weight: bold"></project></span>
</pre></div>
<h2><tt>/src/test/resources/jetty-users.properties</tt></h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #4070a0">test_user</span><span style="color: #666666">=</span><span style="color: #4070a0">test_user,AUTHORIZED_USER</span>
</pre></div>
<h1>Using the <tt>keytool-maven-plugin</tt> for generating a certificate for SSL</h1>
<p>In order to enable server authentication, the Jetty instance needs to have access to a server certificate to be sent out in the SSL handshake. I did some investigation and found that there was a plugin, <tt>keytool-maven-plugin</tt>, which would allow you to automate self-signed certificate generation in the maven execution. I modified the project's pom as follows:</>
<h2><tt>pom.xml</tt> (version 2)</h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #062873; font-weight: bold"><project</span> <span style="color: #4070a0">xmlns="http://maven.apache.org/POM/4.0.0"</span>
<span>...</span>
<span><build</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><plugins></span>
...
<span style="color: #062873; font-weight: bold"><plugin></span>
<span style="color: #062873; font-weight: bold"><groupId></span>org.codehaus.mojo<span style="color: #062873; font-weight: bold"></groupId></span>
<span style="color: #062873; font-weight: bold"><artifactId></span>keytool-maven-plugin<span style="color: #062873; font-weight: bold"></artifactId></span>
<span style="color: #062873; font-weight: bold"><executions></span>
<span style="color: #062873; font-weight: bold"><execution></span>
<span style="color: #062873; font-weight: bold"><phase></span>generate-resources<span style="color: #062873; font-weight: bold"></phase></span>
<span style="color: #062873; font-weight: bold"><id></span>clean<span style="color: #062873; font-weight: bold"></id></span>
<span style="color: #062873; font-weight: bold"><goals></span>
<span style="color: #062873; font-weight: bold"><goal></span>clean<span style="color: #062873; font-weight: bold"></goal></span>
<span style="color: #062873; font-weight: bold"></goals></span>
<span style="color: #062873; font-weight: bold"></execution></span>
<span style="color: #062873; font-weight: bold"><execution></span>
<span style="color: #062873; font-weight: bold"><phase></span>generate-resources<span style="color: #062873; font-weight: bold"></phase></span>
<span style="color: #062873; font-weight: bold"><id></span>genkey<span style="color: #062873; font-weight: bold"></id></span>
<span style="color: #062873; font-weight: bold"><goals></span>
<span style="color: #062873; font-weight: bold"><goal></span>genkey<span style="color: #062873; font-weight: bold"></goal></span>
<span style="color: #062873; font-weight: bold"></goals></span>
<span style="color: #062873; font-weight: bold"></execution></span>
<span style="color: #062873; font-weight: bold"></executions></span>
<span style="color: #062873; font-weight: bold"><configuration></span>
<span style="color: #062873; font-weight: bold"><keystore></span>${project.build.directory}/jetty-ssl.keystore<span style="color: #062873; font-weight: bold"></keystore></span>
<span style="color: #062873; font-weight: bold"><dname></span>cn=active-active.blogspot.com<span style="color: #062873; font-weight: bold"></dname></span>
<span style="color: #062873; font-weight: bold"><keypass></span>jetty6<span style="color: #062873; font-weight: bold"></keypass></span>
<span style="color: #062873; font-weight: bold"><storepass></span>jetty6<span style="color: #062873; font-weight: bold"></storepass></span>
<span style="color: #062873; font-weight: bold"><alias></span>jetty6<span style="color: #062873; font-weight: bold"></alias></span>
<span style="color: #062873; font-weight: bold"><keyalg></span>RSA<span style="color: #062873; font-weight: bold"></keyalg></span>
<span style="color: #062873; font-weight: bold"></configuration></span>
<span style="color: #062873; font-weight: bold"></plugin></span>
...
<span style="color: #062873; font-weight: bold"></plugins></span>
...
<span style="color: #062873; font-weight: bold"></build></span>
...
<span style="color: #062873; font-weight: bold"></project></span>
</pre></div>
<h1>Adding SSL support to Jetty</h1>
<p>Now, we have a way for the client to authenticate itself, a realm for assigning that client's roles, and a keystore. We just need to tell Jetty how to expose an SSL port to the world.</p>
<h2><tt>pom.xml</tt> (version 3)</h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #062873; font-weight: bold"><project</span> <span style="color: #4070a0">xmlns="http://maven.apache.org/POM/4.0.0"</span>
<span>...</span>
<span><build</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><plugins></span>
...
<span style="color: #062873; font-weight: bold"><plugin></span>
<span style="color: #062873; font-weight: bold"><groupId></span>org.mortbay.jetty<span style="color: #062873; font-weight: bold"></groupId></span>
<span style="color: #062873; font-weight: bold"><artifactId></span>jetty-maven-plugin<span style="color: #062873; font-weight: bold"></artifactId></span>
<span style="color: #062873; font-weight: bold"><version></span>7.3.0.v20110203<span style="color: #062873; font-weight: bold"></version></span>
<span style="color: #062873; font-weight: bold"><configuration></span>
...
<span style="color: #062873; font-weight: bold"></userRealms></span>
<span style="color: #062873; font-weight: bold"><connectors></span>
<span style="color: #062873; font-weight: bold"><connector</span> <span style="color: #4070a0">implementation="org.eclipse.jetty.server.nio.SelectChannelConnector"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><port></span>8080<span style="color: #062873; font-weight: bold"></port></span>
<span style="color: #062873; font-weight: bold"><maxIdleTime></span>60000<span style="color: #062873; font-weight: bold"></maxIdleTime></span>
<span style="color: #062873; font-weight: bold"></connector></span>
<span style="color: #062873; font-weight: bold"><connector</span> <span style="color: #4070a0">implementation="org.eclipse.jetty.server.ssl.SslSocketConnector"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><port></span>8443<span style="color: #062873; font-weight: bold"></port></span>
<span style="color: #062873; font-weight: bold"><maxIdleTime></span>60000<span style="color: #062873; font-weight: bold"></maxIdleTime></span>
<span style="color: #062873; font-weight: bold"><keystore></span>${project.build.directory}/jetty-ssl.keystore<span style="color: #062873; font-weight: bold"></keystore></span>
<span style="color: #062873; font-weight: bold"><password></span>jetty6<span style="color: #062873; font-weight: bold"></password></span>
<span style="color: #062873; font-weight: bold"><keyPassword></span>jetty6<span style="color: #062873; font-weight: bold"></keyPassword></span>
<span style="color: #062873; font-weight: bold"></connector></span>
<span style="color: #062873; font-weight: bold"></connectors></span>
<span style="color: #062873; font-weight: bold"><loginServices></span>
...
<span style="color: #062873; font-weight: bold"></configuration></span>
<span style="color: #062873; font-weight: bold"></plugin></span>
...
<span style="color: #062873; font-weight: bold"></plugins></span>
...
<span style="color: #062873; font-weight: bold"></build></span>
...
<span style="color: #062873; font-weight: bold"></project></span>
</pre></div>
<p>A big thank-you to mrhaki and his article <a href="http://mrhaki.blogspot.com/2009/05/configure-maven-jetty-plugin-for-ssl.html">Configure Maven Jetty Plugin for SSL Communication</a> for the assist.</p>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-73924315322248358722011-01-23T22:51:00.001-05:002018-04-10T18:04:06.231-04:00Testing Toolbelt: SpringJUnit4ClassRunner<p>The <tt>org.springframework.test.context.junit4.SpringJUnit4ClassRunner</tt> class is another implementation of the JUnit <tt>TestRunner</tt> class which is used to enable various features of Spring for every run of the test class and every test within it. To use the features provided by the <tt>SpringJUnit4ClassRunner</tt> class, you need to mark the class using the <tt>RunWith</tt> annotation using <tt>SpringJUnit4ClassRunner</tt> as its parameter.</p>
<p>In addition to the custom test runner, you will want to mark the class with the <tt>ContextConfiguration</tt> annotation. The <tt>ContextConfiguration</tt> annotation is used to mark classes which will automatically read a Spring configuration file and use it to create an <tt>ApplicationContext</tt>. By default, this file located at <tt><package path>/<test class name>-context.xml</tt>. Use the <tt>locations</tt> argument to over-ride.</p>
<p>The <tt>ApplicationContext</tt> used by the Spring-integrated test will only be loaded once for the whole test class. This behavior can be over-ridden by annotating a test method with the <tt>DirtiesContext</tt> annotation, which causes the <tt>ApplicationContext</tt> to be reloaded after the test method completes.</p>
<h2>Test Property Injection</h2>
<p>Fresh versions of the properties for the test, including the class under test, can be automatically injected for every test, either by name or type. A test class property marked with the <tt>Autowired</tt> annotation will be automatically set by <b>type</b> from the test's <tt>ApplicationContext</tt>. However, if there are multiple instances of the property's type, it could be better to set the property by name. The <tt>Resource</tt> is used to mark test class properties which should be set by <b>name</b> from the test's <tt>ApplicationContext</tt>.</p>
<h2>Transaction Management</h2>
<p>With the declaration of a <tt>TransactionManager</tt> bean, and the use of the <tt>Transactional</tt> annotation, transaction boundaries are declarative and are automatically managed. Simply fire up the test and forget about whether or not your integration test changed the state of the database you're using to test.</p>
<p>The <tt>Transactional</tt> annotation is used within transactional Spring tests to mark test classes and methods which should have a transactional nature applied to them. When used to annotate a test class, a transaction context will be created before each test method is executed. After each test method, the transaction will be rolled-back. This will add the overhead of creating and managing a transaction for every test method in that class, so it is usually better to annotate the test methods with <tt>@Transactional</tt> instead. This will cause a similar effect to annotating the class, but only annotated test methods will be transactional.
Usage of this annotation requires a <tt>TransactionManager</tt> named <tt>transactionManager</tt> to be defined in the test's <tt>ApplicationContext</tt>.</p>
<p>Similar in purpose to the <tt>Before</tt> and <tt>After</tt> annotations provided by JUnit, methods decorated with either the <tt>BeforeTransaction</tt> or <tt>AfterTransaction</tt> annotation will be run before/after any test method which is affected by the <tt>Transactional</tt> annotation (i.e. all methods in a class decorated with <tt>@Transactional</tt>, or each annotated test method when marked individually. Methods annotated with the <tt>BeforeTransaction</tt> or <tt>AfterTransaction</tt> annotations must be public and return no value.</p>
<h2>Integration Test Helper Classes</h2>
<p>When using the <tt>SpringJUnit4ClassRunner</tt>, you're given access to the <tt>ApplicationContext</tt> instance and a simplified interface for interacting with your integration test database through <tt>JdbcTemplate</tt>/<tt>SimpleJdbcTemplate</tt>.</p>
<h2><tt>spring-testing-sample.java</tt></h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #555555; font-weight: bold">@RunWith</span><span style="color: #666666">(</span>SpringJUnit4ClassRunner<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">)</span>
<span style="color: #555555; font-weight: bold">@ContextConfiguration</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">ITSpringExample</span> <span style="color: #666666">{</span>
<span style="color: #555555; font-weight: bold">@Resource</span> Object dependencyByName<span style="color: #666666">;</span>
<span style="color: #555555; font-weight: bold">@Autowired</span> String dependencyByType<span style="color: #666666">;</span>
<span style="color: #555555; font-weight: bold">@BeforeTransaction</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">preTransaction</span><span style="color: #666666">()</span> <span style="color: #666666">{</span>
System<span style="color: #666666">.</span><span style="color: #4070a0">out</span><span style="color: #666666">.</span><span style="color: #4070a0">println</span><span style="color: #666666">(</span><span style="color: #4070a0">"before transaction"</span><span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@AfterTransaction</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">postTransaction</span><span style="color: #666666">()</span> <span style="color: #666666">{</span>
System<span style="color: #666666">.</span><span style="color: #4070a0">out</span><span style="color: #666666">.</span><span style="color: #4070a0">println</span><span style="color: #666666">(</span><span style="color: #4070a0">"after transaction"</span><span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@Transactional</span>
<span style="color: #555555; font-weight: bold">@Test</span> <span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> test1<span style="color: #666666">()</span> <span style="color: #666666">{</span>
<span style="color: #60a0b0; font-style: italic">// before this test, a transaction will be created</span>
<span style="color: #60a0b0; font-style: italic">// after this test, the transaction will be rolled-back</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@Test</span> <span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> test2<span style="color: #666666">()</span> <span style="color: #666666">{</span>
<span style="color: #60a0b0; font-style: italic">// no transaction will be created around this test</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@DirtiesContext</span>
<span style="color: #555555; font-weight: bold">@Test</span> <span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> test3<span style="color: #666666">()</span> <span style="color: #666666">{</span>
dependencyByName <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">;</span>
<span style="color: #666666">}</span>
<span style="color: #666666">}</span>
</pre></div>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com2tag:blogger.com,1999:blog-6841148002347889687.post-84744195588372738262011-01-23T15:54:00.001-05:002018-04-10T17:43:46.824-04:00Testing Toolbelt: Groovy<p><a href="http://groovy-lang.org/">Groovy</a>, the apparent golden child of Java, is a mostly dynamic-typed JVM language which seeks to add functionality to the core Java language such that writing and testing code is much easier and requires less boiler-plate code. Some of the features provided by Groovy that I have found useful for testing are:
<a name='more'></a>
<dl>
<dt>GroovyBean Properties and Constructors</dt>
<dd><p>Groovy attempts to simplify the usage of bean-type object by providing some shortcuts for accesses and assignments. By default, every class accessed through Groovy code is decorated with a default constructor which takes a map (property->value), and a getter and setter for each field defined in the class (for which there is not already a getter/setter). The constructor is a simple way to provide values to properties of the new instance.</p>
<h3><tt>properties-sample.groovy</tt></h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">Customer</span> <span style="color: #666666">{</span>
Integer id
String name
Date dob
<span style="color: #007020; font-weight: bold">static</span> <span style="color: #902000">void</span> <span style="color: #06287e">main</span><span style="color: #666666">(</span>args<span style="color: #666666">)</span> <span style="color: #666666">{</span>
<span style="color: #60a0b0; font-style: italic">/* note: the next statement is functionally equivalent to:</span>
<span style="color: #60a0b0; font-style: italic"> * in Groovy:</span>
<span style="color: #60a0b0; font-style: italic"> * def customer = new Customer()</span>
<span style="color: #60a0b0; font-style: italic"> * customer.id = 1</span>
<span style="color: #60a0b0; font-style: italic"> * customer.name = "Gromit"</span>
<span style="color: #60a0b0; font-style: italic"> * customer.dob = new Date()</span>
<span style="color: #60a0b0; font-style: italic"> * in Java (provided all of the set<name> methods were defined):</span>
<span style="color: #60a0b0; font-style: italic"> * Customer customer = new Customer();</span>
<span style="color: #60a0b0; font-style: italic"> * customer.setId(1);</span>
<span style="color: #60a0b0; font-style: italic"> * customer.setName("Gromit");</span>
<span style="color: #60a0b0; font-style: italic"> * customer.setDob(new Date());</span>
<span style="color: #60a0b0; font-style: italic"> */</span>
<span style="color: #902000">def</span> customer <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> Customer<span style="color: #666666">(</span><span style="color: #002070; font-weight: bold">id:</span><span style="color: #40a070">1</span><span style="color: #666666">,</span> <span style="color: #002070; font-weight: bold">name:</span><span style="color: #4070a0">"Gromit"</span><span style="color: #666666">,</span> <span style="color: #002070; font-weight: bold">dob:</span><span style="color: #007020; font-weight: bold">new</span> Date<span style="color: #666666">())</span>
<span style="color: #60a0b0; font-style: italic">// note: calls the getName() method defined below</span>
println<span style="color: #666666">(</span><span style="color: #4070a0">"Hello ${customer.name}"</span><span style="color: #666666">)</span>
<span style="color: #60a0b0; font-style: italic">// note: references the id field directly</span>
println<span style="color: #666666">(</span><span style="color: #4070a0">"Your id is ${customer.id}"</span><span style="color: #666666">)</span>
<span style="color: #60a0b0; font-style: italic">// ...not really, the Groovy compiler adds in a</span>
<span style="color: #60a0b0; font-style: italic">// default getter for the field.</span>
<span style="color: #666666">}</span>
<span style="color: #007020; font-weight: bold">public</span> String <span style="color: #06287e">getName</span><span style="color: #666666">()</span> <span style="color: #666666">{</span>
println <span style="color: #4070a0">"in getter"</span>
<span style="color: #007020; font-weight: bold">return</span> name
<span style="color: #666666">}</span>
<span style="color: #666666">}</span>
</pre></div>
</dd>
<dt>Token Replacement</dt>
<dd><p>In Groovy, the <tt>String</tt> class is enhanced to allow for the use of tokens within a <tt>String</tt> literal. These tokens are of the form <tt>${<property>}</tt> and will use the properties values available at the time of creation. Refer back to the above example to see some at work.</p></dd>
<dt>Collection Literals</dt>
<dd><p>Easily create a list by using the <tt>[<value>]</tt> syntax, a range by using the <tt><start>..<end></tt> syntax, and a map by using the <tt>[<key>:<value>]</tt> syntax.</p>
<h3><tt>collection-sample.groovy</tt></h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #902000">def</span> emptyList <span style="color: #666666">=</span> <span style="color: #666666">[]</span>
<span style="color: #902000">def</span> list <span style="color: #666666">=</span> <span style="color: #666666">[</span><span style="color: #40a070">1</span><span style="color: #666666">,</span> <span style="color: #40a070">2</span><span style="color: #666666">,</span> <span style="color: #40a070">3</span><span style="color: #666666">,</span> <span style="color: #40a070">4</span><span style="color: #666666">,</span> <span style="color: #40a070">5</span><span style="color: #666666">,</span> <span style="color: #40a070">6</span><span style="color: #666666">,</span> <span style="color: #40a070">7</span><span style="color: #666666">,</span> <span style="color: #40a070">8</span><span style="color: #666666">]</span>
<span style="color: #902000">def</span> range <span style="color: #666666">=</span> <span style="color: #40a070">1</span><span style="color: #666666">..</span><span style="color: #40a070">8</span>
<span style="color: #007020; font-weight: bold">assert</span> list <span style="color: #666666">==</span> range
<span style="color: #902000">def</span> emptyMap <span style="color: #666666">=</span> <span style="color: #666666">[:]</span>
<span style="color: #902000">def</span> map <span style="color: #666666">=</span> <span style="color: #666666">[</span><span style="color: #40a070">1</span><span style="color: #666666">:</span><span style="color: #40a070">2</span><span style="color: #666666">,</span> <span style="color: #40a070">3</span><span style="color: #666666">:</span><span style="color: #40a070">4</span><span style="color: #666666">,</span> <span style="color: #40a070">5</span><span style="color: #666666">:</span><span style="color: #40a070">6</span><span style="color: #666666">]</span>
</pre></div>
</dd>
<dt>Closures</dt>
<dd><p>Closures are simply blocks of code surrounded by curly braces, which can be treated as reference types. Closures may declare arguments and may return values. Closures may be stored in variables.</p>
<h3><tt>closure-sample.groovy</tt></h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #60a0b0; font-style: italic">// times is actually a method which takes a number</span>
<span style="color: #60a0b0; font-style: italic">// (the target of the call) and a closure</span>
<span style="color: #60a0b0; font-style: italic">// print 0 to 10 using a closure</span>
<span style="color: #40a070">10</span><span style="color: #666666">.</span><span style="color: #4070a0">times</span> <span style="color: #666666">{</span><span style="color: #902000">int</span> var <span style="color: #666666">-></span> println var<span style="color: #666666">}</span> <span style="color: #60a0b0; font-style: italic">// explicit closure variable and type</span>
<span style="color: #40a070">10</span><span style="color: #666666">.</span><span style="color: #4070a0">times</span> <span style="color: #666666">{</span>var <span style="color: #666666">-></span> println var<span style="color: #666666">}</span> <span style="color: #60a0b0; font-style: italic">// explicit closure variable</span>
<span style="color: #40a070">10</span><span style="color: #666666">.</span><span style="color: #4070a0">times</span> <span style="color: #666666">{</span>println it<span style="color: #666666">}</span> <span style="color: #60a0b0; font-style: italic">// no variable declaration</span>
</pre></div>
</dd>
<dt>Iteration (<tt>each</tt>)</dt>
<dd><p>Iteration of arrays, ranges, lists, and maps has been simplified by the addition of the <tt>each</tt> method.</p>
<h3><tt>each-sample.groovy</tt></h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #60a0b0; font-style: italic">// each is actually a method which takes an iterable</span>
<span style="color: #60a0b0; font-style: italic">// (the target of the call) and a closure</span>
<span style="color: #60a0b0; font-style: italic">// print 0 to 10 using a closure and a range (also an iterable)</span>
<span style="color: #666666">(</span><span style="color: #40a070">0</span><span style="color: #666666">..</span><span style="color: #40a070">10</span><span style="color: #666666">).</span><span style="color: #4070a0">each</span> <span style="color: #666666">{</span><span style="color: #902000">int</span> var <span style="color: #666666">-></span> println var<span style="color: #666666">}</span> <span style="color: #60a0b0; font-style: italic">// explicit closure variable and type</span>
<span style="color: #666666">(</span><span style="color: #40a070">0</span><span style="color: #666666">..</span><span style="color: #40a070">10</span><span style="color: #666666">).</span><span style="color: #4070a0">each</span> <span style="color: #666666">{</span>var <span style="color: #666666">-></span> println var<span style="color: #666666">}</span> <span style="color: #60a0b0; font-style: italic">// explicit closure variable</span>
<span style="color: #666666">(</span><span style="color: #40a070">0</span><span style="color: #666666">..</span><span style="color: #40a070">10</span><span style="color: #666666">).</span><span style="color: #4070a0">each</span> <span style="color: #666666">{</span>println it<span style="color: #666666">}</span> <span style="color: #60a0b0; font-style: italic">// no variable declaration</span>
<span style="color: #60a0b0; font-style: italic">// print a map</span>
<span style="color: #666666">[</span><span style="color: #40a070">1</span><span style="color: #666666">:</span><span style="color: #40a070">10</span><span style="color: #666666">,</span> <span style="color: #40a070">2</span><span style="color: #666666">:</span><span style="color: #40a070">20</span><span style="color: #666666">,</span> <span style="color: #40a070">3</span><span style="color: #666666">:</span><span style="color: #40a070">30</span><span style="color: #666666">].</span><span style="color: #4070a0">each</span> <span style="color: #666666">{</span>key<span style="color: #666666">,</span> value <span style="color: #666666">-></span> println <span style="color: #4070a0">"${key}-${value}"</span><span style="color: #666666">}</span>
</pre></div>
</dd>
<dt>Coercion (Map and Closure)</dt>
<dd><p>Any map or closure may be interpreted as an instance of a specific type simply by using <tt>as <type></tt>. This allows you to easily create stand-in objects, provided they have a public default (no-arg) constructor.</p>
<h3><tt>coercion-sample.groovy</tt></h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #902000">def</span> map1 <span style="color: #666666">=</span> <span style="color: #666666">{</span>println <span style="color: #4070a0">"hi"</span><span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">as</span> Map
map1<span style="color: #666666">.</span><span style="color: #4070a0">get</span><span style="color: #666666">(</span><span style="color: #4070a0">"george"</span><span style="color: #666666">)</span> <span style="color: #60a0b0; font-style: italic">// prints hi</span>
map1<span style="color: #666666">[</span><span style="color: #4070a0">"george"</span><span style="color: #666666">]</span> <span style="color: #60a0b0; font-style: italic">// different way of doing the same thing in Groovy</span>
<span style="color: #902000">def</span> map2 <span style="color: #666666">=</span> <span style="color: #666666">[</span><span style="color: #002070; font-weight: bold">get:</span> <span style="color: #666666">{</span>key <span style="color: #666666">-></span> <span style="color: #007020; font-weight: bold">return</span> <span style="color: #4070a0">"value"</span><span style="color: #666666">}]</span> <span style="color: #007020; font-weight: bold">as</span> HashMap
map2<span style="color: #666666">[</span><span style="color: #4070a0">"key"</span><span style="color: #666666">]</span> <span style="color: #666666">=</span> <span style="color: #4070a0">"hello"</span>
<span style="color: #007020; font-weight: bold">assert</span> map2<span style="color: #666666">[</span><span style="color: #4070a0">"key"</span><span style="color: #666666">]</span> <span style="color: #666666">==</span> <span style="color: #4070a0">"value"</span>
</pre></div>
</dd>
<dt><a href="http://groovy.codehaus.org/groovy-jdk/">GDK</a></dt>
<dd><p>Through the default meta-class implementations used by Groovy, many useful methods (many taking advantage of closures) have been added to the standard Java classes. There's too much to list here, but know that many of the above examples use GDK methods.</p></dd>
<dt><a href="http://groovy.codehaus.org/Unit+Testing"><tt>GroovyTestCase</tt></a></dt>
<dd><p>The <tt>GroovyTestCase</tt> class contains a large portion of the testing functionality used by basic Groovy. Since the Groovy team have pledged backwards-compatibility with JDK 1.4, they have also stuck with the non-annotation-based version of JUnit(3.8.*) as a basis for their testing helper class. This is not as bad as it sounds, as many of the language features of Groovy make up for the missing capabilities of JUnit 4.4. Every test class defined using groovy must be a sub-class of <tt>GroovyTestCase</tt>. Each test method must be public, return <tt>void</tt>, and be named <tt>test<something></tt>.</p>
<dl>
<dt><tt>assert*</tt></dt>
<dd><p>all of the <tt>assert*</tt> methods provided by JUnit are also present in the <tt>GroovyTestCase</tt> class.</p></dd>
<dt><tt>shouldFail(<Throwable>)</tt></dt>
<dd><p>similar to the <tt>Test</tt> annotation when used with the <tt>expected</tt> argument, the <tt>shouldFail</tt> method takes a <tt>Throwable</tt> class type and a closure, executes the closure, and fails if an instance of <tt>Throwable</tt> is not thrown within the closure.</p>
<h3><tt>shouldFail-sample.groovy</tt></h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> shouldFail<span style="color: #666666">(</span>ArrayIndexOutOfBoundsException<span style="color: #666666">)</span> <span style="color: #666666">{</span>
println <span style="color: #666666">(</span><span style="color: #40a070">0</span><span style="color: #666666">..</span><span style="color: #40a070">4</span><span style="color: #666666">)[</span><span style="color: #40a070">10</span><span style="color: #666666">];</span>
<span style="color: #666666">}</span>
</pre></div>
</dd>
</dl></dd>
<dt><tt>StubFor</tt> and <tt>MockFor</tt></dt>
<dd><p>The <tt>StubFor</tt>/<tt>MockFor</tt> classes can be used within Groovy to create stand-in objects when coercion won't work or when you need to over-ride the behavior of a constructor.</p>
<h3><tt>stubfor-sample.groovy</tt></h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #60a0b0; font-style: italic">//can't use Map coercion, File does not have default constructor.</span>
<span style="color: #902000">def</span> mockFileType <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> MockFor<span style="color: #666666">(</span>File<span style="color: #666666">)</span>
mockFileType<span style="color: #666666">.</span><span style="color: #4070a0">demand</span><span style="color: #666666">.</span><span style="color: #4070a0">exists</span> <span style="color: #666666">{</span> <span style="color: #007020; font-weight: bold">return</span> <span style="color: #007020; font-weight: bold">true</span> <span style="color: #666666">}</span>
mockFileType<span style="color: #666666">.</span><span style="color: #4070a0">use</span> <span style="color: #666666">{</span>
<span style="color: #902000">def</span> f <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> File<span style="color: #666666">(</span><span style="color: #4070a0">'DOES_NOT_EXIST.TXT'</span><span style="color: #666666">)</span>
assertThat<span style="color: #666666">(</span>f<span style="color: #666666">.</span><span style="color: #4070a0">exists</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">true</span><span style="color: #666666">))</span>
<span style="color: #666666">}</span>
</pre></div>
</dd></dl>
<footer>
<h3>References/Related:</h3>
<ul>
<li><a href="https://www.amazon.com/gp/product/1934356093/ref=as_li_ss_tl?ie=UTF8&tag=activeactivec-20&linkCode=as2&camp=217145&creative=399369&creativeASIN=1934356093">Programming Groovy: Dynamic Productivity for the Java Developer (Pragmatic Programmers)</a><img src="https://www.assoc-amazon.com/e/ir?t=activeactivec-20&l=as2&o=1&a=1934356093&camp=217145&creative=399369" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;"></li>
</ul>
</footer>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-74954997670571959262011-01-22T16:35:00.001-05:002018-04-10T17:12:47.171-04:00Spring Note: SqlUpdate<p>The <tt>org.springframework.jdbc.object.SqlUpdate</tt> class is another tool that I use a lot. This class encapsulates <tt>INSERT</tt>, <tt>UPDATE</tt>, and <tt>DELETE</tt> queries as beans defined within your application context. In most situations, you will be using the <tt>SqlUpdate</tt> class as-is with multiple configurations within a DAO's context. Since the class is not abstract, it is quite easy to extend for creating dummy/mock instances for testing.</p>
<a name='more'></a>
<h3><tt>ITSpringJdbc.java</tt></h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #555555; font-weight: bold">@RunWith</span><span style="color: #666666">(</span>SpringJUnit4ClassRunner<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">)</span>
<span style="color: #555555; font-weight: bold">@ContextConfiguration</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">ITSpringJdbc</span> <span style="color: #666666">{</span>
<span style="color: #555555; font-weight: bold">@Resource</span> SqlUpdate updateBean<span style="color: #666666">;</span>
<span style="color: #555555; font-weight: bold">@Resource</span> JdbcTemplate jdbcTemplate<span style="color: #666666">;</span>
<span style="color: #555555; font-weight: bold">@Transactional</span>
<span style="color: #555555; font-weight: bold">@Test</span> <span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> testUpdate<span style="color: #666666">()</span> <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">final</span> String<span style="color: #666666">[]</span> args <span style="color: #666666">=</span> <span style="color: #666666">{</span> <span style="color: #4070a0">"T"</span> <span style="color: #666666">};</span>
updateBean<span style="color: #666666">.</span><span style="color: #4070a0">update</span><span style="color: #666666">(</span>args<span style="color: #666666">);</span>
<span style="color: #007020; font-weight: bold">final</span> <span style="color: #902000">int</span> count <span style="color: #666666">=</span> jdbcTemplate<span style="color: #666666">.</span><span style="color: #4070a0">queryForInt</span><span style="color: #666666">(</span>
<span style="color: #4070a0">"select count(*) from DUAL where dummy = 'T'"</span><span style="color: #666666">);</span>
assertThat<span style="color: #666666">(</span>count<span style="color: #666666">,</span> is<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">));</span>
<span style="color: #666666">}</span>
<span style="color: #666666">}</span>
</pre></div>
<h3><tt>ITSpringJdbc-context.xml</tt></h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020"><?xml version="1.0" encoding="UTF-8"?></span>
<span style="color: #062873; font-weight: bold"><beans</span> <span style="color: #4070a0">xmlns="http://www.springframework.org/schema/beans"</span>
<span style="color: #4070a0">xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span>
<span style="color: #4070a0">xmlns:util="http://www.springframework.org/schema/util"</span>
<span style="color: #4070a0">xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd</span>
<span style="color: #4070a0"> http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><bean</span> <span style="color: #4070a0">id="dataSource.properties"</span>
<span style="color: #4070a0">class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="locations"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><list></span>
<span style="color: #062873; font-weight: bold"><value></span>classpath:connection.properties<span style="color: #062873; font-weight: bold"></value></span>
<span style="color: #062873; font-weight: bold"></list></span>
<span style="color: #062873; font-weight: bold"></property></span>
<span style="color: #062873; font-weight: bold"></bean></span>
<span style="color: #062873; font-weight: bold"><bean</span> <span style="color: #4070a0">id="dataSource"</span>
<span style="color: #4070a0">class="org.springframework.jdbc.datasource.DriverManagerDataSource"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="driverClassName"</span> <span style="color: #4070a0">value="${driverClassName}"</span> <span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="url"</span> <span style="color: #4070a0">value="${uri}"</span> <span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="username"</span> <span style="color: #4070a0">value="${username}"</span> <span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="password"</span> <span style="color: #4070a0">value="${password}"</span> <span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"></bean></span>
<span style="color: #062873; font-weight: bold"><bean</span> <span style="color: #4070a0">id="updateBean"</span>
<span style="color: #4070a0">class="org.springframework.jdbc.object.SqlUpdate"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="dataSource"</span> <span style="color: #4070a0">ref="dataSource"</span><span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="sql"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><value></span>
insert into DUAL (dummy) values (?)
<span style="color: #062873; font-weight: bold"></value></span>
<span style="color: #062873; font-weight: bold"></property></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="types"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><list</span> <span style="color: #4070a0">value-type="java.lang.Integer"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><util:constant</span>
<span style="color: #4070a0">static-field="java.sql.Types.VARCHAR"</span> <span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"></list></span>
<span style="color: #062873; font-weight: bold"></property></span>
<span style="color: #062873; font-weight: bold"></bean></span>
<span style="color: #062873; font-weight: bold"><bean</span> <span style="color: #4070a0">id="jdbcTemplate"</span>
<span style="color: #4070a0">class="org.springframework.jdbc.core.JdbcTemplate"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="dataSource"</span> <span style="color: #4070a0">ref="dataSource"</span><span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"></bean></span>
<span style="color: #062873; font-weight: bold"></beans></span>
</pre></div>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-65019679061769399382011-01-22T02:25:00.001-05:002011-01-23T22:57:52.921-05:00New Group: Columbus Software Craftsmanship<p>As you may or may not know, I have two homes: SW Indiana, and Columbus, Ohio. Since I spend 75% or more of my time in SW Indiana and there are few opportunities in this area for networking/learning the craft, I'm always happy to learn about new groups of like-minded people in my other home.</p>
<p>I found this group through a random <a href="https://twitter.com/marcpeabody/status/28479928127193088">tweet</a> from Marc Peabody. He mentioned that they would be trying out some Scala Koans and included a link to the group's <a href="http://groups.google.com/group/columbus-craftsmanship">Google Groups</a> site. Since joining the group earlier today, I've found the details for the Scala Koans night and I've been informed of interest in running a <a href="http://www.coderetreat.com/">Code Retreat</a> event at the beginning of April in Columbus.</p>
<p>I haven't made it to any meetings yet (they're still a pretty new group), but I've had some friendly conversations in e-mail with members of the group and have met some of the other members through NFJS, COJUG, CRB, etc... Sounds like it should be a pretty good time when I'm able to make it.</p>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-15988025284839008472011-01-22T02:06:00.001-05:002018-04-10T17:09:45.948-04:00Maven note: exec-maven-plugin<p>I'm currently working on a development package containing a series of <tt>.xsd</tt> files which will be used to define the external interface for our web service. Due to some other project constraints, it was decided that this package also needed to include the <tt>.wsdl</tt> files which will further define the web service.</p>
<a name='more'></a>
<p>I'm a lazy <i>(the good kind)</i> programmer, so I decided that I did not want to update these files every time the schema changed nor did I want to make anyone else figure it out later. I wrote a quick utility for creating the <tt>.wsdl</tt> files, based on the current <tt>.xsd</tt> files. Since we're already expecting to use Spring-WS for message dispatching, I wrote some file generation code around the <tt>org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition</tt> class and wrote up a Spring configuration which put it all together.</p>
<p>My next task was to figure out a way to get this utility to run within the context of the Maven <tt>package</tt> phase. Since the code needed to generate the <tt>.wsdl</tt> files was the only code in this development package, it made sense to hook into the <tt>prepare-package</tt> phase instead of the <tt>generate-sources</tt> phase. Now that I knew when the utility should run, I just needed to figure out a way to do it. One Google search later, and I had the <tt><a href="http://www.mojohaus.org/exec-maven-plugin/">exec-maven-plugin</a></tt>. This Maven plugin provides two goals which can be hooked into arbitrary phases in the Maven life cycle:
<ul>
<li><tt>exec</tt> -- execute an arbitrary executable from within the Maven runtime</li>
<li><tt>java</tt> -- execute the <tt>main</tt> method, with arguments, of a specified class, from within the Maven runtime</li>
</ul></p>
<p>So I set up my pom as shown below, and ran <tt>mvn package</tt>. The end result was a <tt>.jar</tt> file which contained both the <tt>.xsd</tt> and the <tt>.wsdl</tt> files we need. One <tt>mvn deploy</tt> later and these files were now available to all who needed them.</p>
<h2>pom.xml</h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #062873; font-weight: bold"><project></span>
...
<span style="color: #062873; font-weight: bold"><build></span>
<span style="color: #062873; font-weight: bold"><plugins></span>
<span style="color: #062873; font-weight: bold"><plugin></span>
<span style="color: #062873; font-weight: bold"><groupId></span>org.codehaus.mojo<span style="color: #062873; font-weight: bold"></groupId></span>
<span style="color: #062873; font-weight: bold"><artifactId></span>exec-maven-plugin<span style="color: #062873; font-weight: bold"></artifactId></span>
<span style="color: #062873; font-weight: bold"><version></span>1.2<span style="color: #062873; font-weight: bold"></version></span>
<span style="color: #062873; font-weight: bold"><executions></span>
<span style="color: #062873; font-weight: bold"><execution></span>
<span style="color: #062873; font-weight: bold"><phase></span>prepare-package<span style="color: #062873; font-weight: bold"></phase></span>
<span style="color: #062873; font-weight: bold"><goals></span>
<span style="color: #062873; font-weight: bold"><goal></span>java<span style="color: #062873; font-weight: bold"></goal></span>
<span style="color: #062873; font-weight: bold"></goals></span>
<span style="color: #062873; font-weight: bold"></execution></span>
<span style="color: #062873; font-weight: bold"></executions></span>
<span style="color: #062873; font-weight: bold"><configuration></span>
<span style="color: #062873; font-weight: bold"><mainClass></span>my.utility.ClassName<span style="color: #062873; font-weight: bold"></mainClass></span>
<span style="color: #062873; font-weight: bold"><arguments></span>
<span style="color: #062873; font-weight: bold"><argument></span>${project.build.outputDirectory}<span style="color: #062873; font-weight: bold"></argument></span>
<span style="color: #062873; font-weight: bold"></arguments></span>
<span style="color: #062873; font-weight: bold"></configuration></span>
<span style="color: #062873; font-weight: bold"></plugin></span>
<span style="color: #062873; font-weight: bold"></plugins></span>
<span style="color: #062873; font-weight: bold"></build></span>
...
<span style="color: #062873; font-weight: bold"></project></span>
</pre></div>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com2tag:blogger.com,1999:blog-6841148002347889687.post-39372926802312326172011-01-22T01:08:00.001-05:002018-04-10T17:07:14.537-04:00Testing Toolbelt: Hamcrest Matchers<p>The <a href="http://hamcrest.org">Hamcrest Matchers</a> framework contains a series of <tt>Matcher</tt> classes which help implement comparison and assertion methods in a type-safe, declarative manner. When used in tests, the Matchers framework will produce more legible test code and more helpful failure messages. The Matchers framework is partially included in the JUnit 4.4 package and some portions can be used effectively. But, the full power of the framework can only be unleashed by including the real Hamcrest Matchers jar within your testing environment.</p>
<a name='more'></a>
<h2>Matchers</h2>
<p>The <tt>org.hamcrest.Matchers</tt> class in the Hamcrest framework provides a series of methods, intended to be used with <tt>import static</tt>, which supply various pre-defined <tt>org.hamcrest.core.Matcher</tt> instances.
<ul>
<li><tt>is</tt> -- The simplest matcher, most times behaves just as syntactical sugar around other matchers. But, if an instance of <tt>Class</tt> is passed, it behaves like the <tt>Matcher</tt> produced by <tt>instanceOf</tt>. If passed any other value, behaves like the <tt>Matcher</tt> produced by <tt>equalsTo</tt>. see <tt>org.hamcrest.core.Is</tt></li>
<li><tt>equalTo</tt> -- Verifies that the test value is equal to the value used to instantiate the <tt>Matcher</tt>. see <tt>org.hamcrest.core.IsEqual</tt></li>
<li><tt>instanceOf</tt> -- Verifies that the test value is assignable to the <tt>Class</tt> value used to instantiate the <tt>Matcher</tt>. see <tt>org.hamcrest.core.IsInstanceOf</tt></li>
<li><tt>nullValue</tt>/<tt>nonNullValue</tt> -- Verifies that the test value is null-valued/not-null-valued. see <tt>org.hamcrest.core.IsNull</tt></li>
<li><tt>startsWith</tt>/<tt>containsString</tt>/<tt>endsWith</tt> -- Verifies that the test value (<tt>String</tt>\-typed) begins with, contains, or ends with the value used to instatiate the <tt>Matcher</tt>. see <tt>org.hamcrest.core.StringStartsWith</tt>, <tt>org.hamcrest.core.StringContains</tt>, and <tt>org.hamcrest.core.StringEndsWith</tt></li>
<li><tt>arrayWithSize</tt>/<tt>emptyArray</tt>/<tt>hasSize</tt>/<tt>empty</tt> -- Verifies that the test value is an array/collection that either has the given number of elements/is empty. see <tt>org.hamcrest.core.IsArrayWithSize</tt>, <tt>org.hamcrest.core.IsCollectionWithSize</tt>, and <tt>org.hamcrest.core.IsEmptyCollection</tt></li>
<li><tt>lessThan</tt>/<tt>lessThanOrEqualTo</tt>/<tt>greaterThanOrEqualTo</tt>/<tt>greaterThan</tt> -- Verifies that the test value is strictly less than/less than/greater than/strictly greater than the provided value. see <tt>org.hamcrest.core.OrderingComparison</tt></li>
</ul></p>
<h2>Examples</h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">MatcherSample</span> <span style="color: #666666">{</span>
<span style="color: #555555; font-weight: bold">@Test</span> <span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> matcherSample<span style="color: #666666">()</span> <span style="color: #666666">{</span>
<span style="color: #60a0b0; font-style: italic">// doesn't compile, type-safety in action</span>
<span style="color: #60a0b0; font-style: italic">// assertThat(1, is("VALUE"));</span>
<span style="color: #60a0b0; font-style: italic">// is, with a Class-typed operand...</span>
assertThat<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE"</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>String<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">));</span>
<span style="color: #60a0b0; font-style: italic">// ...is resolved to this...</span>
assertThat<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE"</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>instanceOf<span style="color: #666666">(</span>String<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">)));</span>
<span style="color: #60a0b0; font-style: italic">// ...which is then unwrapped to this</span>
assertThat<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE"</span><span style="color: #666666">,</span> instanceOf<span style="color: #666666">(</span>String<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">));</span>
<span style="color: #60a0b0; font-style: italic">// is, with a reference-type operand...</span>
assertThat<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE"</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE"</span><span style="color: #666666">));</span>
<span style="color: #60a0b0; font-style: italic">// ...is resolved to this...</span>
assertThat<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE"</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>equalTo<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE"</span><span style="color: #666666">)));</span>
<span style="color: #60a0b0; font-style: italic">// ... which is then unwrapped to this</span>
assertThat<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE"</span><span style="color: #666666">,</span> equalTo<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE"</span><span style="color: #666666">));</span>
<span style="color: #60a0b0; font-style: italic">// is, with a primitive value</span>
assertThat<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">));</span>
<span style="color: #60a0b0; font-style: italic">// assert null-valued</span>
assertThat<span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>nullValue<span style="color: #666666">()));</span>
<span style="color: #60a0b0; font-style: italic">// assert null-valued, checking type</span>
assertThat<span style="color: #666666">((</span>String<span style="color: #666666">)</span> <span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>nullValue<span style="color: #666666">(</span>String<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">)));</span>
<span style="color: #60a0b0; font-style: italic">// assert non-null</span>
assertThat<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE"</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>notNullValue<span style="color: #666666">()));</span>
<span style="color: #60a0b0; font-style: italic">// Matchers for Strings</span>
<span style="color: #60a0b0; font-style: italic">// you could use is() with these, but is more readable without</span>
assertThat<span style="color: #666666">(</span><span style="color: #4070a0">"VALUABLE"</span><span style="color: #666666">,</span> startsWith<span style="color: #666666">(</span><span style="color: #4070a0">"VALU"</span><span style="color: #666666">));</span>
assertThat<span style="color: #666666">(</span><span style="color: #4070a0">"VALUABLE"</span><span style="color: #666666">,</span> containsString<span style="color: #666666">(</span><span style="color: #4070a0">"LUA"</span><span style="color: #666666">));</span>
assertThat<span style="color: #666666">(</span><span style="color: #4070a0">"VALUABLE"</span><span style="color: #666666">,</span> endsWith<span style="color: #666666">(</span><span style="color: #4070a0">"ABLE"</span><span style="color: #666666">));</span>
<span style="color: #60a0b0; font-style: italic">// Matchers for Arrays and Collections</span>
<span style="color: #007020; font-weight: bold">final</span> String<span style="color: #666666">[]</span> strings1 <span style="color: #666666">=</span> <span style="color: #666666">{};</span>
assertThat<span style="color: #666666">(</span>strings1<span style="color: #666666">,</span> is<span style="color: #666666">(</span>emptyArray<span style="color: #666666">()));</span>
assertThat<span style="color: #666666">(</span>strings1<span style="color: #666666">,</span> is<span style="color: #666666">(</span>arrayWithSize<span style="color: #666666">(</span><span style="color: #40a070">0</span><span style="color: #666666">)));</span>
assertThat<span style="color: #666666">(</span>Arrays<span style="color: #666666">.</span><span style="color: #4070a0">asList</span><span style="color: #666666">(</span>strings1<span style="color: #666666">),</span> hasSize<span style="color: #666666">(</span><span style="color: #40a070">0</span><span style="color: #666666">));</span>
<span style="color: #007020; font-weight: bold">final</span> String<span style="color: #666666">[]</span> strings2 <span style="color: #666666">=</span> <span style="color: #666666">{</span> <span style="color: #4070a0">"VALUE_1"</span><span style="color: #666666">,</span> <span style="color: #4070a0">"VALUE_2"</span> <span style="color: #666666">};</span>
assertThat<span style="color: #666666">(</span>strings2<span style="color: #666666">,</span> is<span style="color: #666666">(</span>arrayWithSize<span style="color: #666666">(</span><span style="color: #40a070">2</span><span style="color: #666666">)));</span>
assertThat<span style="color: #666666">(</span>strings2<span style="color: #666666">,</span> is<span style="color: #666666">(</span>arrayContaining<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE_1"</span><span style="color: #666666">,</span> <span style="color: #4070a0">"VALUE_2"</span><span style="color: #666666">)));</span>
assertThat<span style="color: #666666">(</span>Arrays<span style="color: #666666">.</span><span style="color: #4070a0">asList</span><span style="color: #666666">(</span>strings2<span style="color: #666666">),</span> hasSize<span style="color: #666666">(</span><span style="color: #40a070">2</span><span style="color: #666666">));</span>
assertThat<span style="color: #666666">(</span>Arrays<span style="color: #666666">.</span><span style="color: #4070a0">asList</span><span style="color: #666666">(</span>strings2<span style="color: #666666">),</span> contains<span style="color: #666666">(</span><span style="color: #4070a0">"VALUE_1"</span><span style="color: #666666">,</span> <span style="color: #4070a0">"VALUE_2"</span><span style="color: #666666">));</span>
<span style="color: #60a0b0; font-style: italic">// Matchers for Numerics</span>
assertThat<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>lessThan<span style="color: #666666">(</span><span style="color: #40a070">10</span><span style="color: #666666">)));</span>
assertThat<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>greaterThan<span style="color: #666666">(</span><span style="color: #40a070">0</span><span style="color: #666666">)));</span>
assertThat<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>lessThanOrEqualTo<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">)));</span>
assertThat<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>greaterThanOrEqualTo<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">)));</span>
<span style="color: #60a0b0; font-style: italic">// use both/allOf/either/anyOf for composition of matchers</span>
<span style="color: #60a0b0; font-style: italic">// both/allOf is equivalent to and'ing the Matchers</span>
assertThat<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>both<span style="color: #666666">(</span>greaterThan<span style="color: #666666">(</span><span style="color: #40a070">0</span><span style="color: #666666">)).</span><span style="color: #4070a0">and</span><span style="color: #666666">(</span>lessThan<span style="color: #666666">(</span><span style="color: #40a070">10</span><span style="color: #666666">))));</span>
assertThat<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>allOf<span style="color: #666666">(</span>greaterThan<span style="color: #666666">(</span><span style="color: #40a070">0</span><span style="color: #666666">),</span> lessThan<span style="color: #666666">(</span><span style="color: #40a070">10</span><span style="color: #666666">))));</span>
<span style="color: #60a0b0; font-style: italic">// either/anyOf is equivalent to or'ing the Matchers</span>
assertThat<span style="color: #666666">(</span><span style="color: #40a070">100</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>either<span style="color: #666666">(</span>lessThan<span style="color: #666666">(</span><span style="color: #40a070">0</span><span style="color: #666666">)).</span><span style="color: #4070a0">or</span><span style="color: #666666">(</span>greaterThan<span style="color: #666666">(</span><span style="color: #40a070">10</span><span style="color: #666666">))));</span>
assertThat<span style="color: #666666">(</span><span style="color: #40a070">100</span><span style="color: #666666">,</span> is<span style="color: #666666">(</span>anyOf<span style="color: #666666">(</span>lessThan<span style="color: #666666">(</span><span style="color: #40a070">0</span><span style="color: #666666">),</span> greaterThan<span style="color: #666666">(</span><span style="color: #40a070">10</span><span style="color: #666666">))));</span>
<span style="color: #666666">}</span>
<span style="color: #666666">}</span>
</pre></div>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-84796982165786464242011-01-22T00:24:00.001-05:002018-04-10T17:05:12.104-04:00Testing Toolbelt: JUnit<p>The <a href="http://www.junit.org">JUnit</a> framework is arguably the de-facto standard for unit testing java code, and is also the basis of many other testing frameworks (unit or otherwise). Using the JUnit framework, one can quickly run a test method, class, or suite and get one of three responses:
<ul>
<li>Success: All of the assertions in the test method passed, no fail calls were encountered, and no unexpected exceptions were thrown.</li>
<li>Failure: One of the assertions in the test method failed or a fail call was encountered.</li>
<li>Error: An unexpected <tt>java.lang.Throwable</tt> was thrown within the test method's body.</li>
</ul></p>
<a name='more'></a>
<p>For the sake of brevity, and since I am mostly using Java 1.6 these days, this discussion will focus on JUnit 4.4 which is based on annotations and static imports instead of specially-named methods and the extension of the <tt>junit.framework.TestCase</tt> class.</p>
<h2>@Test</h2>
<p>Every method that should be run as a test should be annotated with the <tt>org.junit.Test</tt> annotation. The <tt>Test</tt> annotation must be used on only <tt>public void</tt> methods and the annotated method can only take parameters when used in conjunction with the <tt>Parameterized</tt> annotation discussed below. The <tt>Test</tt> annotation can take two optional arguments:
<dl>
<dt><tt>expected</tt></dt>
<dd>An optional argument to the <tt>Test</tt> annotation which declares that the test method is expected to throw a <tt>Throwable</tt> of the defined type. If the method does not throw a <tt>Throwable</tt> of an appropriate type, the test will fail. If any other <tt>Throwable</tt> escapes the method body, the test will be considered in error.</dd>
<dt><tt>timeout</tt></dt>
<dd>An optional argument to the <tt>Test</tt> annotation which declares that the test method is expected to complete within the defined number of milliseconds. If the method does not return in time, the test fails.
</dd>
</dl></p>
<h2>@Before/@After/@BeforeClass/@AfterClass</h2>
<p>Public methods marked with these annotations will be run before each test (<tt>setUp()</tt>), after each test(<tt>tearDown()</tt>), before each test suite, or after each test suite. These annotations are usually used to setup and reset the environment in which the tests are running.</p>
<h2>Assert</h2>
<p>The <tt>org.junit.Assert</tt> class is expected to be used through the use of static imports, and contains a large number of static methods which can be used to ensure that the elements of a test are in an expected state. Each of the <tt>assert*</tt> methods has two forms:
<dl>
<dt><tt>assert*(actual, expected)</tt></dt>
<dd>performs the assertion and fails with a default failure message.</dd>
<dt><tt>assert*(message, actual, expected)</tt></dt>
<dd>performs the assertion and fails with a custom failure message. (sometimes in addition to the default message)</dd>
</dl></p>
<p>Here are some of the main assertion methods:
<dl>
<dt><tt>assertNull(param)</tt>/<tt>assertNotNull(param)</tt></dt>
<dd>Asserts that the parameter is(not) null-valued.</dd>
<dt><tt>assertTrue(param)</tt>/<tt>assertFalse(param)</tt></dt>
<dd>Asserts that the parameter is true|false?</dd>
<dt><tt>assertEquals(actual, expected)</tt>/<tt>assertArrayEquals(actual, expected)</tt></dt>
<dd>Asserts that <tt>actual</tt> and <tt>expected</tt> are <tt>equal()</tt>.</dd>
<dt><tt>fail(message)</tt></dt>
<dd>Causes the current test to immediately fail. Use this when writing custom <tt>assert</tt> methods or when creating new empty test methods.</dd>
<dt><tt>assertThat(actual, Matcher)</tt></dt>
<dd>The entry point into the Hamcrest Matcher framework, which will be covered by itself in a different post. This method, when used in conjunction with a <tt>Matcher</tt> instance is more capable, and produces more helpful failure output than the other JUnit <tt>assert*</tt> methods.</dd>
</dl>
</p>
<h2>Parameterized</h2>
<p>The <tt>org.junit.runners.Parameterized</tt> class is a non-default JUnit <tt>TestRunner</tt> implementation which allows for the creation of a series of test class instances, one for each of the parameter sets defined in the parameter generation method. Each of these test class instances will then be executed.</p>
<p>Every class which uses the <tt>Parameterized</tt> class as a runner must provide a source method for the parameters. The parameter source method is marked using the <tt>org.junit.runners.Parameters</tt> annotation. The parameter source method must be static and return a <tt>Collection</tt> of values or arrays. Each element in the returned collection represents a single test class execution and will be passed to the constructor for a new instance of the test class. The constructor must accept the same number of arguments and those arguments must be of a compatible type to those contained in each element of the returned collection.
</p>
<h3>An example of <tt>Parameterized</tt> usage:</h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #60a0b0; font-style: italic">/*</span>
<span style="color: #60a0b0; font-style: italic"> * This test class, when run, produces results showing</span>
<span style="color: #60a0b0; font-style: italic"> * three test runs with two successes and one failure.</span>
<span style="color: #60a0b0; font-style: italic"> */</span>
<span style="color: #555555; font-weight: bold">@RunWith</span><span style="color: #666666">(</span>Parameterized<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">)</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">ParameterizedTest</span> <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">final</span> Integer value<span style="color: #666666">;</span>
<span style="color: #555555; font-weight: bold">@Parameters</span> <span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">static</span> Collection<span style="color: #666666"><</span>integer<span style="color: #666666">></span> getParameters<span style="color: #666666">()</span> <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">return</span> Arrays<span style="color: #666666">.</span><span style="color: #4070a0">asList</span><span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">,</span> <span style="color: #40a070">3</span><span style="color: #666666">,</span> <span style="color: #40a070">10</span><span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #06287e">ParameterizedTest</span><span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">final</span> Integer value<span style="color: #666666">)</span> <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">this</span><span style="color: #666666">.</span><span style="color: #4070a0">value</span> <span style="color: #666666">=</span> value<span style="color: #666666">;</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@Test</span> <span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> isLessThanFive<span style="color: #666666">()</span> <span style="color: #666666">{</span>
assertTrue<span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">this</span><span style="color: #666666">.</span><span style="color: #4070a0">value</span> <span style="color: #666666"><</span> <span style="color: #40a070">5</span><span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #666666">}</span>
</pre></div>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-576152213159202902011-01-21T23:56:00.002-05:002018-04-10T17:00:43.127-04:00Spring Note: RowMapper/MappingSqlQuery<p>There are a couple of interesting Spring classes which keep coming up in my daily work: <tt>RowMapper</tt> and <tt>MappingSqlQuery</tt>.</p>
<a name='more'></a>
<h1>RowMapper</h1>
<p>The <tt>RowMapper</tt> class is an interface which defines only one method which turns a single row from a <tt>ResultSet</tt> into a domain-useable object. While you can use a generic implementation of this class for producing column name/value <tt>Map</tt>s, my typical usage has been to create domain objects from the result of a specific set of queries.</p>
<h1>MappingSqlQuery</h1>
<p>The <tt>MappingSqlQuery</tt> class is intended to be used for <tt>SELECT</tt> queries and can use a <tt>RowMapper</tt> implementation to create a result <tt>List</tt> of the appropriate type, hiding the intermediate <tt>ResultSet</tt> from the outside world.</p>
<p>These classes, when taken together, provide excellent tools for creating the read methods for DAO classes which are concise and testable.</p>
<h3><tt>ITSpringJdbc.java</tt></h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #555555; font-weight: bold">@RunWith</span><span style="color: #666666">(</span>SpringJUnit4ClassRunner<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">)</span>
<span style="color: #555555; font-weight: bold">@ContextConfiguration</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">ITSpringJdbc</span> <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">TestMapper</span> <span style="color: #007020; font-weight: bold">implements</span> RowMapper <span style="color: #666666">{</span>
<span style="color: #555555; font-weight: bold">@Override</span>
<span style="color: #007020; font-weight: bold">public</span> Map<span style="color: #666666"><</span>String<span style="color: #666666">,</span> String<span style="color: #666666">></span> mapRow<span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">final</span> ResultSet rs<span style="color: #666666">,</span> <span style="color: #007020; font-weight: bold">final</span> <span style="color: #902000">int</span> index<span style="color: #666666">)</span>
<span style="color: #007020; font-weight: bold">throws</span> SQLException <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">final</span> Map<span style="color: #666666"><</span>String<span style="color: #666666">,</span> String<span style="color: #666666">></span> m <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> HashMap<span style="color: #666666"><</span>String<span style="color: #666666">,</span> String<span style="color: #666666">>();</span>
<span style="color: #007020; font-weight: bold">final</span> ResultSetMetaData md <span style="color: #666666">=</span> rs<span style="color: #666666">.</span><span style="color: #4070a0">getMetaData</span><span style="color: #666666">();</span>
<span style="color: #007020; font-weight: bold">for</span> <span style="color: #666666">(</span><span style="color: #902000">int</span> i <span style="color: #666666">=</span> <span style="color: #40a070">0</span><span style="color: #666666">;</span> i <span style="color: #666666"><</span> md<span style="color: #666666">.</span><span style="color: #4070a0">getColumnCount</span><span style="color: #666666">();</span> i<span style="color: #666666">++)</span> <span style="color: #666666">{</span>
m<span style="color: #666666">.</span><span style="color: #4070a0">put</span><span style="color: #666666">(</span>md<span style="color: #666666">.</span><span style="color: #4070a0">getColumnName</span><span style="color: #666666">(</span>i<span style="color: #666666">),</span> rs<span style="color: #666666">.</span><span style="color: #4070a0">getString</span><span style="color: #666666">(</span>i<span style="color: #666666">));</span>
<span style="color: #666666">}</span>
<span style="color: #007020; font-weight: bold">return</span> m<span style="color: #666666">;</span>
<span style="color: #666666">}</span>
<span style="color: #666666">}</span>
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">TestSelect</span> <span style="color: #007020; font-weight: bold">extends</span> MappingSqlQuery <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">final</span> TestMapper mapper <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> TestMapper<span style="color: #666666">();</span>
<span style="color: #555555; font-weight: bold">@Override</span>
<span style="color: #007020; font-weight: bold">protected</span> Object <span style="color: #06287e">mapRow</span><span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">final</span> ResultSet rs<span style="color: #666666">,</span> <span style="color: #007020; font-weight: bold">final</span> <span style="color: #902000">int</span> index<span style="color: #666666">)</span>
<span style="color: #007020; font-weight: bold">throws</span> SQLException <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">return</span> mapper<span style="color: #666666">.</span><span style="color: #4070a0">mapRow</span><span style="color: #666666">(</span>rs<span style="color: #666666">,</span> index<span style="color: #666666">);</span>
<span style="color: #666666">}</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@Resource</span> TestSelect selectBean<span style="color: #666666">;</span>
<span style="color: #555555; font-weight: bold">@Resource</span> TestMapper mappingBean<span style="color: #666666">;</span>
<span style="color: #555555; font-weight: bold">@Resource</span> JdbcTemplate jdbcTemplate<span style="color: #666666">;</span>
<span style="color: #555555; font-weight: bold">@Test</span> <span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> testSelect<span style="color: #666666">()</span> <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">final</span> String<span style="color: #666666">[]</span> args <span style="color: #666666">=</span> <span style="color: #666666">{</span> <span style="color: #4070a0">"X"</span> <span style="color: #666666">};</span>
<span style="color: #007020; font-weight: bold">final</span> Object result <span style="color: #666666">=</span> selectBean<span style="color: #666666">.</span><span style="color: #4070a0">findObject</span><span style="color: #666666">(</span>args<span style="color: #666666">);</span>
assertThat<span style="color: #666666">(</span>result<span style="color: #666666">,</span> is<span style="color: #666666">(</span>notNullValue<span style="color: #666666">());</span>
assertThat<span style="color: #666666">(</span>result<span style="color: #666666">,</span> is<span style="color: #666666">(</span>Map<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">));</span>
<span style="color: #007020; font-weight: bold">final</span> Map map <span style="color: #666666">=</span> <span style="color: #666666">(</span>Map<span style="color: #666666">)</span> result<span style="color: #666666">;</span>
assertThat<span style="color: #666666">(</span>map<span style="color: #666666">,</span> hasSize<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">));</span>
assertThat<span style="color: #666666">(</span>map<span style="color: #666666">.</span><span style="color: #4070a0">containsKey</span><span style="color: #666666">(</span><span style="color: #4070a0">"dummy"</span><span style="color: #666666">),</span> is<span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">true</span><span style="color: #666666">));</span>
assertThat<span style="color: #666666">(</span>map<span style="color: #666666">.</span><span style="color: #4070a0">get</span><span style="color: #666666">(</span><span style="color: #4070a0">"dummy"</span><span style="color: #666666">),</span> is<span style="color: #666666">(</span><span style="color: #4070a0">"X"</span><span style="color: #666666">));</span>
<span style="color: #666666">}</span>
<span style="color: #555555; font-weight: bold">@Test</span> <span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> testMapper<span style="color: #666666">()</span> <span style="color: #666666">{</span>
<span style="color: #007020; font-weight: bold">final</span> SqlRowSet rs <span style="color: #666666">=</span> jdbcTemplate<span style="color: #666666">.</span><span style="color: #4070a0">queryForRowSet</span><span style="color: #666666">(</span>
<span style="color: #4070a0">"select dummy from table"</span><span style="color: #666666">);</span>
<span style="color: #007020; font-weight: bold">final</span> Object o <span style="color: #666666">=</span> mappingBean<span style="color: #666666">.</span><span style="color: #4070a0">mapRow</span><span style="color: #666666">(</span>rs<span style="color: #666666">,</span> <span style="color: #40a070">0</span><span style="color: #666666">);</span>
assertThat<span style="color: #666666">(</span>o<span style="color: #666666">,</span> is<span style="color: #666666">(</span>notNullValue<span style="color: #666666">());</span>
assertThat<span style="color: #666666">(</span>o<span style="color: #666666">,</span> is<span style="color: #666666">(</span>Map<span style="color: #666666">.</span><span style="color: #4070a0">class</span><span style="color: #666666">));</span>
<span style="color: #007020; font-weight: bold">final</span> Map map <span style="color: #666666">=</span> <span style="color: #666666">(</span>Map<span style="color: #666666">)</span> o<span style="color: #666666">;</span>
assertThat<span style="color: #666666">(</span>map<span style="color: #666666">,</span> hasSize<span style="color: #666666">(</span><span style="color: #40a070">1</span><span style="color: #666666">));</span>
assertThat<span style="color: #666666">(</span>map<span style="color: #666666">.</span><span style="color: #4070a0">containsKey</span><span style="color: #666666">(</span><span style="color: #4070a0">"dummy"</span><span style="color: #666666">),</span> is<span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">true</span><span style="color: #666666">));</span>
assertThat<span style="color: #666666">(</span>map<span style="color: #666666">.</span><span style="color: #4070a0">get</span><span style="color: #666666">(</span><span style="color: #4070a0">"dummy"</span><span style="color: #666666">),</span> is<span style="color: #666666">(</span><span style="color: #4070a0">"X"</span><span style="color: #666666">));</span>
<span style="color: #666666">}</span>
<span style="color: #666666">}</span>
</pre></div>
<h3><tt>ITSpringJdbc-context.xml</tt></h3>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020"><?xml version="1.0" encoding="UTF-8"?></span>
<span style="color: #062873; font-weight: bold"><beans</span> <span style="color: #4070a0">xmlns="http://www.springframework.org/schema/beans"</span>
<span style="color: #4070a0">xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span>
<span style="color: #4070a0">xmlns:util="http://www.springframework.org/schema/util"</span>
<span style="color: #4070a0">xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd</span>
<span style="color: #4070a0"> http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><bean</span> <span style="color: #4070a0">id="dataSource.properties"</span>
<span style="color: #4070a0">class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="locations"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><list></span>
<span style="color: #062873; font-weight: bold"><value></span>classpath:connection.properties<span style="color: #062873; font-weight: bold"></value></span>
<span style="color: #062873; font-weight: bold"></list></span>
<span style="color: #062873; font-weight: bold"></property></span>
<span style="color: #062873; font-weight: bold"></bean></span>
<span style="color: #062873; font-weight: bold"><bean</span> <span style="color: #4070a0">id="dataSource"</span>
<span style="color: #4070a0">class="org.springframework.jdbc.datasource.DriverManagerDataSource"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="driverClassName"</span> <span style="color: #4070a0">value="${driverClassName}"</span> <span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="url"</span> <span style="color: #4070a0">value="${uri}"</span> <span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="username"</span> <span style="color: #4070a0">value="${username}"</span> <span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="password"</span> <span style="color: #4070a0">value="${password}"</span> <span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"></bean></span>
<span style="color: #062873; font-weight: bold"><bean</span> <span style="color: #4070a0">id="selectBean"</span>
<span style="color: #4070a0">class="TestSelect"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="dataSource"</span> <span style="color: #4070a0">ref="dataSource"</span> <span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="sql"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><value></span>
select dummy from table where dummy = ?
<span style="color: #062873; font-weight: bold"></value></span>
<span style="color: #062873; font-weight: bold"></property></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="types"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><list</span> <span style="color: #4070a0">value-type="java.lang.Integer"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><util:constant</span>
<span style="color: #4070a0">static-field="java.sql.Types.VARCHAR"</span> <span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"></list></span>
<span style="color: #062873; font-weight: bold"></property></span>
<span style="color: #062873; font-weight: bold"></bean></span>
<span style="color: #062873; font-weight: bold"><bean</span> <span style="color: #4070a0">id="mappingBean"</span>
<span style="color: #4070a0">class="TestMapper"</span><span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"><bean</span> <span style="color: #4070a0">id="jdbcTemplate"</span>
<span style="color: #4070a0">class="org.springframework.jdbc.core.JdbcTemplate"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="dataSource"</span> <span style="color: #4070a0">ref="dataSource"</span><span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"></bean></span>
<span style="color: #062873; font-weight: bold"></beans></span>
</pre></div>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-89327026153097943052011-01-21T23:32:00.001-05:002011-01-23T22:56:36.235-05:00Clearing the BacklogI've had several posts brewing in the background. I'm going to pump out a few posts tonight and finally bid them a fond adieu. So, here they come fast and furious, and maybe not as deep as I originally expected them to be.Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-21826215335007996152010-06-30T09:26:00.001-04:002018-04-10T16:51:27.628-04:00Learning Ruby: Knowing.net Exercise #1<p>I've just finished exercise #1 from: <a href="http://www.knowing.net/index.php/2006/06/16/15-exercises-to-know-a-programming-language-part-1/">knowing.net</a>. Please feel free to critique this code, I am serious about learning Ruby and getting introduced to members of the community.</p>
<a name='more'></a>
<h2>proj1.rb</h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #60a0b0; font-style: italic"># Write a program that takes as its arguments one of the words ’sum’,</span>
<span style="color: #60a0b0; font-style: italic"># ‘product’, ‘mean’, or ’sqrt’ followed by a series of numbers. The</span>
<span style="color: #60a0b0; font-style: italic"># program applies the appropriate function to the series.</span>
<span style="color: #60a0b0; font-style: italic"># the mathn library makes the Math.sqrt call below behave better in</span>
<span style="color: #60a0b0; font-style: italic"># situations involving negative sums.</span>
<span style="color: #007020">require</span> <span style="color: #4070a0">'mathn'</span>
<span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">Array</span>
<span style="color: #007020; font-weight: bold">def</span> <span style="color: #06287e">sum</span>
<span style="color: #60a0b0; font-style: italic"># missed the inject method on my first</span>
<span style="color: #60a0b0; font-style: italic"># skim of the 'Programming Ruby' appendix.</span>
<span style="color: #007020">self</span><span style="color: #666666">.</span>inject {<span style="color: #666666">|</span>sum, i<span style="color: #666666">|</span> sum <span style="color: #666666">+</span> i}<span style="color: #666666">.</span>to_f
<span style="color: #007020; font-weight: bold">end</span>
<span style="color: #007020; font-weight: bold">def</span> <span style="color: #06287e">product</span>
<span style="color: #007020">self</span><span style="color: #666666">.</span>inject(<span style="color: #40a070">1</span>) {<span style="color: #666666">|</span>product, i<span style="color: #666666">|</span> product <span style="color: #666666">*</span> i}<span style="color: #666666">.</span>to_f
<span style="color: #007020; font-weight: bold">end</span>
<span style="color: #007020; font-weight: bold">def</span> <span style="color: #06287e">mean</span>
<span style="color: #007020">self</span><span style="color: #666666">.</span>sum <span style="color: #666666">/</span> <span style="color: #007020">self</span><span style="color: #666666">.</span>size
<span style="color: #007020; font-weight: bold">end</span>
<span style="color: #007020; font-weight: bold">def</span> <span style="color: #06287e">sqrt</span>
<span style="color: #60add5">Math</span><span style="color: #666666">.</span>sqrt(<span style="color: #007020">self</span><span style="color: #666666">.</span>sum)
<span style="color: #007020; font-weight: bold">end</span>
<span style="color: #007020; font-weight: bold">end</span>
<span style="color: #007020; font-weight: bold">raise</span> <span style="color: #4070a0">"usage: ruby proj1.rb {sum|product|mean|sqrt} {value}+"</span> <span style="color: #007020; font-weight: bold">if</span> <span style="color: #60add5">ARGV</span><span style="color: #666666">.</span>size <span style="color: #666666"><</span> <span style="color: #40a070">2</span>
<span style="color: #60add5">Allowed_commands</span> <span style="color: #666666">=</span> <span style="color: #666666">[</span><span style="color: #4070a0">"sum"</span>, <span style="color: #4070a0">"product"</span>, <span style="color: #4070a0">"mean"</span>, <span style="color: #4070a0">"sqrt"</span><span style="color: #666666">]</span>
command <span style="color: #666666">=</span> <span style="color: #60add5">ARGV</span><span style="color: #666666">.</span>shift<span style="color: #666666">.</span>downcase
<span style="color: #007020; font-weight: bold">raise</span> <span style="color: #4070a0">"unknown command: </span><span style="color: #70a0d0; font-style: italic">#{</span>command<span style="color: #70a0d0; font-style: italic">}</span><span style="color: #4070a0">"</span> <span style="color: #007020; font-weight: bold">unless</span> <span style="color: #60add5">Allowed_commands</span><span style="color: #666666">.</span>include? command
<span style="color: #60a0b0; font-style: italic"># I don't like this line, is there a better</span>
<span style="color: #60a0b0; font-style: italic"># way to do String -> numeric conversions?</span>
<span style="color: #60add5">ARGV</span><span style="color: #666666">.</span>collect! {<span style="color: #666666">|</span>i<span style="color: #666666">|</span> i<span style="color: #666666">.</span>to_f}
<span style="color: #007020">puts</span> <span style="color: #007020">eval</span> <span style="color: #60add5">ARGV</span><span style="color: #666666">.</span>to_s <span style="color: #666666">+</span> <span style="color: #4070a0">"."</span> <span style="color: #666666">+</span> command
</pre></div>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-52838095975079160452010-06-29T12:03:00.002-04:002018-04-10T16:49:29.846-04:00Spring Note: PropertyPlaceholderConfigurer<p>Often there are Spring-related configuration options which don't belong inside the final jar/war for a Java application. Either because the options are different for each deployment environment or because the value of the option is sensitive (<i>passwords</i>). The <tt>PropertyPlaceholderConfigurer</tt> class attempts to remedy the management and injection of the values for these options. It reads one or more property files, optionally using system properties for defaults, and uses the values found to fill property placeholders of the form <tt>${property name}</tt> found in the <tt>ApplicationContext</tt> in which the configurer is defined.</p>
<a name='more'></a>
<dl>
<dt>Advantages:</dt>
<dd><ul>
<li>It provides a mechanism for externalizing configuration so that each environment can be configured differently without re-building the application.</li>
<li>It provides a mechanism for injecting test properties at test-time without incurring much development overhead.</li>
<li>Using the <tt>classpath:<file></tt> pseudo-uri enables developers to easily include default properties while still allowing users to over-ride the defaults by adding the location of a properties file to the application's classpath.</li>
<li>The <tt>PropertyPlaceholderConfigurer</tt> is extensible and provides a method, <tt>convertPropertyValue(String)</tt>, which can be over-ridden in a sub-class to handle the encryption of properties.</li>
</ul>
</dd>
<dt>Disadvantages:</dt>
<dd><ul>
<li>The configurer class does not re-load at a regular interval. Changing the properties managed by the configurer requires a restart of the application using it. This can be overcome in some limited situations through a custom sub-class, but for the most part, is not really supported by the Spring container.</li>
<li>Only Spring-managed beans can take advantage of these properties.</li>
</ul>
</dd>
</dl>
<h1>Sample</h1>
<h2>config.xml</h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #062873; font-weight: bold"><bean</span> <span style="color: #4070a0">id="propertyConfigurer"</span>
<span style="color: #4070a0">class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="location"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><value></span>classpath:project.properties<span style="color: #062873; font-weight: bold"></value></span>
<span style="color: #062873; font-weight: bold"></property></span>
<span style="color: #062873; font-weight: bold"></bean></span>
<span style="color: #062873; font-weight: bold"><bean</span> <span style="color: #4070a0">id="dataSource"</span>
<span style="color: #4070a0">class="org.springframework.jdbc.datasource.DriverManagerDataSource"</span><span style="color: #062873; font-weight: bold">></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="driverClassName"</span> <span style="color: #4070a0">value="${jdbc.driver}"</span><span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"><property</span> <span style="color: #4070a0">name="url"</span> <span style="color: #4070a0">value="${jdbc.url}"</span><span style="color: #062873; font-weight: bold">/></span>
<span style="color: #062873; font-weight: bold"></bean></span>
</pre></div>
<h2>project.properties</h2>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #4070a0">jdbc.driver</span><span style="color: #666666">=</span><span style="color: #4070a0">com.mysql.jdbc.Driver</span>
<span style="color: #4070a0">jdbc.url</span><span style="color: #666666">=</span><span style="color: #4070a0">jdbc:mysql:mydb</span>
</pre></div>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-83800014109640048892010-06-23T15:44:00.001-04:002010-06-23T15:46:11.159-04:00Productivity Tools: Launchy<p><a href="http://www.launchy.net/">Launchy</a> is a simple application indexer/launcher for Windows/Linux/Mac OS. It is an application which combines some of the features of the Spotlight and Dock tools in Mac OS. You set up Launchy with a set of folders and file extensions to scan, and it will create a catalog of the files found in those folders. Any of the cataloged files can then be opened quickly by pressing <i>alt+space</i> at any time and then typing some, or all, of the file's name. It is important to note that Launchy does not catalog the contents of the files, only the files' names.</p>
<h2>Lightweight</h2>
<p>Except for the times that Launchy is rebuilding its catalog, you will never see Launchy utilizing your CPU. The index does appear to take up some memory (mine's currently at around 8MB), but that should be expected for this sort of application.</p>
<h2>Filesystem Integration</h2>
<p>Launchy integrates well with your filesystem. That is, you can start typing <tt>C:\Pro</tt>, hit <i>tab</i>, and then hit <i>enter</i> to open up an Explorer window for the Program Files directory. You can use this functionality to get to any folder/file on your filesystem, even those not indexed by Launchy.</p>
<h2>Plugins</h2>
<p>Launchy includes a plugin system and includes some interesting plugins out of the box:
<dl>
<dt>Calcy/GCalc</dt>
<dd>Allows you to do simple calculations and conversions from within Launchy.</dd>
<dt>Controly</dt>
<dd>Indexes the applets from the Control Panel.</dd>
<dt>Runner</dt>
<dd>Create custom commands to run against the command-line.</dd>
<dt>Weby</dt>
<dd>Integrates Launchy with your bookmarks and allows you to do searches against several online search engines from within Launchy.</dd>
</dl></p>
<p>I've also found one additional plugin that has been very useful, the <a href="http://code.google.com/p/putty-launchy-plugin/">PuTTY plugin</a>. This plugin adds all of the saved sessions from your PuTTY installation to Launchy's catalog. This gives you the capability to type <tt>ssh</tt>, hit <i>tab</i>, and see a list of saved PuTTY sessions.</p>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-36590809856702847512010-06-22T11:54:00.001-04:002018-04-10T16:43:09.799-04:00Productivity Tools: Virtual Desktops<p>Virtual desktop systems allow me to set up multiple workspaces within my window manager, each of which contain a separate set of application windows which will only be shown when the workspace is activated. This is a powerful expansion of the idea of application switching (<i>alt+tab</i>) as I can now switch easily between groups of applications, instead of just a single application. By creating task-related workspaces, I am able to stay focused on only the one or two tools that matter for the task I am currently working on, while still having other tools open for access later.</p>
<a name='more'></a>
<p>While virtual desktops have been around for ages in the *nix world, Microsoft still refuses to include these capabilities out of the box. This has led to an array of 3<sup>rd</sup> party tools that provide virtual desktops. I've tried several of these tools over the years, and VirtuaWin is the one which I keep returning to. <a href="http://virtuawin.sourceforge.net/">VirtuaWin</a> is a virtual desktop manager for Windows which gives you a set of virtual desktops and global keystrokes for switching between them.</p>
<p>By default, VirutaWin provides you with two actions: move to another workspace (<i>win+←/↑/→/↓</i>) and move to another workspace with the current window (<i>alt+win+←/↑/→/↓</i>). There is also a module, Smart CoolName, which adds the ability to flash, for a few seconds, the name of the current desktop while switching desktops. You can also do some window management by clicking on the system-tray icon: switch to a specific window/desktop, move a specific window to the current desktop, and flag a window so that is is present on every desktop.</p>
<p>I can usually get away with just four desktops while I'm working:
<dl>
<dt>Work</dt>
<dd>IDE and documentation windows</dd>
<dt>Support</dt>
<dd>tools which support my work, like database clients and JIRA windows</dd>
<dt>Comms</dt>
<dd>my messaging clients and Outlook</dd>
<dt>Other</dt>
<dd>all the other application windows, work-related or not</dd>
</dl></p>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-28225081708126427192010-06-14T15:35:00.008-04:002018-04-10T16:30:16.163-04:00Spring Note: NamedParameterJdbcTemplate<p>While I've been using Spring in various capabilities for some time now, I've never run across a situation where I've needed to execute a sql query with a duplicated parameter from code utilizing Spring. The following is a simple example of the type of query I ran into:
<a name='more'></a>
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #60a0b0; font-style: italic">--Query Version 1</span>
<span style="color: #007020; font-weight: bold">select</span> <span style="color: #666666">*</span> <span style="color: #007020; font-weight: bold">from</span> table_1 <span style="color: #007020; font-weight: bold">where</span> ID <span style="color: #666666">=</span> <span style="color: #666666">?</span>
<span style="color: #007020; font-weight: bold">union</span>
<span style="color: #007020; font-weight: bold">select</span> <span style="color: #666666">*</span> <span style="color: #007020; font-weight: bold">from</span> table_2 <span style="color: #007020; font-weight: bold">where</span> ID <span style="color: #666666">=</span> <span style="color: #666666">?</span>
</pre></div></p>
<p>Using the normal <tt>JdbcTemplate.query</tt> method with this query would require you to create a two-element array which contains the same value in both elements. Silly DRY violation, right? Luckily, some of the folks behind the Spring JDBC packages decided to include a way to define queries where the values of parameters can be specified by name rather than by index. Here's an example using the named parameter syntax handled by the <tt>NamedParameterJdbcTemplate</tt> class:
<!-- HTML generated using hilite.me --><div style="background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020; font-weight: bold">final</span> String query <span style="color: #666666">=</span> <span style="color: #4070a0">"select * from table_1 where ID = :id"</span>
<span style="color: #666666">+</span> <span style="color: #4070a0">" union"</span>
<span style="color: #666666">+</span> <span style="color: #4070a0">" select * from table_2 where ID = :id"</span>
<span style="color: #007020; font-weight: bold">final</span> Map<span style="color: #666666"><</span>String<span style="color: #666666">,</span> String<span style="color: #666666">></span> params <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> HashMap<span style="color: #666666"><</span>String<span style="color: #666666">,</span> String<span style="color: #666666">>();</span>
params<span style="color: #666666">.</span><span style="color: #4070a0">put</span><span style="color: #666666">(</span><span style="color: #4070a0">"id"</span><span style="color: #666666">,</span> id<span style="color: #666666">);</span>
<span style="color: #007020; font-weight: bold">final</span> RowMapper mapper <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> ExampleRowMapper<span style="color: #666666">();</span>
<span style="color: #60a0b0; font-style: italic">// jdbcTemplate is an instance of NamedParameterJdbcTemplate which</span>
<span style="color: #60a0b0; font-style: italic">// has been created in the Spring ApplicationContext using an</span>
<span style="color: #60a0b0; font-style: italic">// appropriately-created DataSource.</span>
<span style="color: #007020; font-weight: bold">final</span> List results <span style="color: #666666">=</span> jdbcTemplate<span style="color: #666666">.</span><span style="color: #4070a0">query</span><span style="color: #666666">(</span>query<span style="color: #666666">,</span> params<span style="color: #666666">,</span> mapper<span style="color: #666666">);</span>
<span style="color: #666666">...</span>
</pre></div></p>
<h4>Interesting note:</h4>
<p>After digging through the Spring's SVN repository, I found that the <tt>NamedParameterJdbcTemplate</tt> class does not appear to rely on the <tt>CallableStatement</tt> class for supporting the named parameter functionality. That means that using this class should be safe for all JDBC drivers(which support <tt>PreparedStatement</tt>s), as the named parameters are handled above the JDBC driver's level.</p>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-82902691818941912542008-09-27T21:43:00.002-04:002018-04-10T16:21:11.507-04:00Quick Post: Scala Syntax PrimerI don't normally want to post and run, but this one was just too good to pass up: <a href="http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html">Scala Syntax Primer</a>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0tag:blogger.com,1999:blog-6841148002347889687.post-75387473112442773712008-08-27T21:38:00.014-04:002018-04-10T16:19:57.475-04:00Meta-programming In Ruby<p>Last Wednesday (08.27.2008), I attended a presentation given by local ruby "hero" Joe O'Brien. He was presenting techniques for meta-programming in Ruby. Meta-programming is a general topic which applies to many languages, however Ruby provides some very basic methods which result in powerful meta-programming tools for creating dynamic run-time functionality and for enhancing the base language.</p>
<a name='more'></a>
<h1>Meta-programming Methods</h1>
<p>Joe started the presentation with a run-down of some of the meta-programming methods exposed by the base object in Ruby.
<ul>
<li><tt>send</tt>--By using the <tt>send</tt> method with a string value (method name) and a list of parameters you can dynamically choose a method to call. This method is provided in conjunction with the message-passing back-bone used by the Ruby interpreter.</li>
<li><tt>method_missing</tt>--Implementations of the <tt>method_missing</tt> message handler can be used to handle messages which are currently not understood by the receiving object. This is an expensive method to use, but can be used to add new functionality in response to an unknown message. ActiveRecord in Rails uses this method to create finder methods when a search is performed.</li>
<li><tt>eval</tt>--Evaluate a string value as arbitrary Ruby code. <span style="font-style:italic;font-weight:bold;">User beware</span> Since this method takes a string argument as the code to be evaluated, any code in that string is not checked by the interpreter until the <tt>eval</tt> statement is executed by the interpreter.</li>
<li><tt>define_method</tt>--Pass a string value (method name) and a block in order to define a new method defined by the given block. This method takes a block as a parameter and is safer to use than the <tt>eval</tt> method.</li>
<li><tt>methods</tt>--Returns an array of the methods currently defined on an object. By calling <tt>methods</tt> on an object and subtracting the result of calling <tt>methods</tt> on that object's supertype, you can easily get a list of the methods defined only within that object.</li>
<li><tt>attr_reader</tt>--The <tt>attr_reader</tt> method is used to make a private field in an object accessible to other objects.</li>
<li><tt>attr_writer</tt>--The <tt>attr_writer</tt> method is used to make a private field in an object settable by other objects.</li>
<li><tt>attr_accessor</tt>--The <tt>attr_accessor</tt> method is used to make a private field in an object accessible and settable by other objects.</li>
</ul></p>
<h1>Example: Declarative Tests and Home-Grown Behavior Driven Development</h1>
<p>Joe, being a "test-first bigot" (his words, not mine), was uncomfortable with the idea that it took him nearly 10 lines of code to test one ActiveRecord <tt>has_many</tt> association. He also expressed his dislike for creating test methods whose names look like <tt>test_a_description_of_the_test</tt>. His iterative approach to creating a declarative version of this this test method started with the original 10 lines of code in his test method. He extracted that method into a method on the Test::Unit::TestCase class, <tt>test_that</tt>, which took three arguments, the model under test, the expected <tt>has_many</tt> association class, and a description of the test as a string. These parameters were used in conjunction with the <tt>define_method</tt> method to create a new method at run-time which executed the original code. Using this technique, Joe stated that he was able to reduce the tests for many of the ActiveRecord capabilites to one-liners.</p>Ryan Ransfordhttp://www.blogger.com/profile/00530398387758124743noreply@blogger.com0