tag:blogger.com,1999:blog-85113535851326036142024-02-07T23:40:23.283-08:00DecodifyThoughts on Coding, Frameworks and Architecture.Barryhttp://www.blogger.com/profile/02017529619785284672noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-8511353585132603614.post-26426439097527018452013-10-30T15:07:00.000-07:002013-10-30T15:07:14.943-07:00AngularJS Unit testing - A helper for stubbing dependent methods that return promisesDeferreds and Promises have changed javascript development for the better. They offer an escape from callback hell. AngularJS supports a version of promises heavily inspired by the popular <a href="https://github.com/kriskowal/q" target="_blank">q library</a>.<br />
<br />
This is great however testing mocking out angularjs service dependencies which return promises was less great!<br />
<div>
<br />
I want to test this:<br />
<br /></div>
<script src="https://gist.github.com/pablojim/7240847.js?file=controller.js"></script>
<br />
<div>
Incidentally this kind of pattern is becoming more common now <a href="https://github.com/angular/angular.js/issues/4158" target="_blank">promise unwrapping is gone</a>.<br />
<br /></div>
<div>
What I wanted:</div>
<div>
<ul>
<li>A way to easily mock the "fetchData" service method</li>
<li>Capability to assert "fetchData" was called the with right arguments ( using jasmine spies)</li>
<li>The mock "fetchData" should return a promise so I can call "then" and use utilities such as $q.all</li>
<li>As little boiler plate code as possible</li>
</ul>
<div>
So I wrote this little helper:</div>
<script src="https://gist.github.com/pablojim/7240847.js?file=jasmineNG.js"></script>
<br />
<div>
<br /></div>
<div>
<br /></div>
<div>
And here is what the full test looks like:<br />
<script src="https://gist.github.com/pablojim/7240847.js?file=controllerTest.js"></script>
<br />
Here is a full working <a href="http://jsfiddle.net/pablojim/SbvqJ/" target="_blank">jsfiddle</a><br />
<br />
There's potential to expand this out having more functionality such as dealing with failing promises and giving more control over when the promise is resolved etc. If you think that's a good idea let me know in the comments.<br />
<br />
<br />
<br />
<br /></div>
<div>
</div>
</div>
Barryhttp://www.blogger.com/profile/02017529619785284672noreply@blogger.com5tag:blogger.com,1999:blog-8511353585132603614.post-59808908765853610432012-12-04T12:35:00.000-08:002012-12-04T12:35:54.205-08:00The Rise of In-Browser Analytics<b>In-browser analytics with large client-side datasets are now feasible and will form an important new trend for the web. </b><br />
<b><br /></b>
Typically now webpages load and display tens of records at a time. I believe loading many thousands of records at a time will become more and more common with the aggregation and filtering then performed in the browser.<br />
<br />
<b>The Current Situation</b><br />
<br />
Many websites have consist of simple drilldowns. For example on my online banking site I see a page with a summary of my recent recent transactions and links to load a new page with more detailed information. e.g. summary page -> individual statement page -> individual transaction page<br />
<br />
More recently there has been a growing trend for single page applications - however the underlying services often still reflect the old model. For example a RESTful api to the banking example could consist of linked summary resources, statement resources and transactions resources with each drilldown causing another roundtrip to the browser.<br />
<br />
This simple drilldown approach often makes sense and will never be fully replaced. However I believe there is an alternative approach that is beginning to make more sense - <b>load all the data and perform the necessary aggregations and display filtering on the client. </b>For example this <a href="http://square.github.com/crossfilter/">crossfilter demo</a> loads 250,000 rows of data and allows interactive filtering and drill down with instantaneous results once the data has been loaded.<br />
<b><br /></b>
<b>Why Change?</b><br />
<b><br /></b>
The simple answer is that in-browser analytics with large client-side datasets can produce better a user experience.<br />
<br />
In my online banking example if all transactions were loaded on the client then monthly statements are just an arbitrary choice. If I want to see what transactions I made on 10 day vacation I can do it instantly. Likewise how much money have ever spent in Starbucks - a near instant result is available.<br />
<br />
In short - by having all the data available in-browser, all interactions with the data can become quicker and certain interactions that were previously impossible become possible. Consider watching your data dynamically change when moving a slider over a date range in comparison to the typical interaction of choosing a date and pressing submit. <br />
<b><br /></b>
<b>Why Now?</b><br />
<b><br /></b>
Until now In-browser Analytics had many technical obstacles however a number of changes have now made this approach viable:<br />
<br />
<ul>
<li><b>Increased Connection Speeds</b>. Downloading a Megabyte of data can be completed in seconds on broadband connections. A single megabyte of compressed data can store hundreds of thousands of rows of data. Utilising Local Storage with incremental updates can also help reduce load-times (and provide an offline capability for mobile users). In addition, from personal experience users are often happy to accept an initial few seconds delay if they have the knowledge that all interactions are lightening fast afterwards.</li>
<li><b>Increased Javascript performance</b>. The ongoing browser speed wars have brought about huge speedups - <a href="http://whyeye.org/browsers/history-of-javascript-performance-chrome/">http://whyeye.org/browsers/history-of-javascript-performance-chrome/</a> This is in addition to gains due to Moore's law. Increased use of HTML5's <a href="http://www.html5rocks.com/en/tutorials/workers/basics/">Webworkers </a>will even allow web-apps to start exploiting multiple cores. In short - modern browsers are now really, really fast.</li>
<li><b>Better Browser Visualisation</b>. Frameworks like <a href="http://d3js.org/">D3</a>, <a href="http://www.highcharts.com/">Highcharts</a>, <a href="http://raphaeljs.com/">Raphael</a> can now routinely handle very large datasets see: <a href="http://www.highcharts.com/stock/demo/data-grouping">http://www.highcharts.com/stock/demo/data-grouping</a>.</li>
<li><b>Better Rich Browser Applications</b>. The filtering and display of large datasets requires complex performant UI frameworks. In addition loading a large dataset only really makes sense if you are going to perform multiple interactions on it - hence the need for a single page app. The recent explosion of rich JavaScript application frameworks has provided the necessary capabilities here - <a href="http://blog.stevensanderson.com/2012/08/01/rich-javascript-applications-the-seven-frameworks-throne-of-js-2012/">http://blog.stevensanderson.com/2012/08/01/rich-javascript-applications-the-seven-frameworks-throne-of-js-2012/</a></li>
<li><b>Better Data Handling</b>. Traditionally all heavy analytics were performed server side and the results exposed with web services. Now there is a growing ecosystem of frameworks to handle large datasets client side. See <a href="http://square.github.com/crossfilter/">crossfilter</a>, <a href="https://github.com/stackd/gauss">gauss</a> and <a href="http://www.jstat.org/">jstat</a></li>
</ul>
<div>
<b>Why Haven't We Seen More of This?</b></div>
<div>
<br /></div>
<br />
This approach is currently quite niche. Many of the components required are still relatively immature and limited to modern browsers and fast connections. Therefore I think In-Browser Analytics may initially find its most fertile ground for internal webapps. In my current role I've focussed on creating analytics websites for internal use only. Due to a managed browser ecosystem (Chrome only) and fast internal networks handling large datasets client-side is made a lot easier.<br />
<br />
There is also a mindset change required. Try telling your fellow developers that your webapp loads a whole years worth of financial records (over 200,000 rows) and then performs statistical analysis on it in JavaScript . This will lead to lots of raised eyebrows. The users don't care though - they just appreciate the fast interface.<br />
<br />
The approach is also best suited to datasets where some statistical summaries can be made. e.g. loading 50,000 book reviews in one go is unlikely to be useful as the user will never read the vast majority of them. This will limit its domain somewhat.<br />
<br />
<b>What Next?</b><br />
<b><br /></b>
Join the revolution! Build some In-Browser Analytic Applications <i>( IBAA? - this really needs a better acronym...)</i><br />
<b><br /></b>
Barryhttp://www.blogger.com/profile/02017529619785284672noreply@blogger.com0tag:blogger.com,1999:blog-8511353585132603614.post-57671675745983256842012-09-24T13:39:00.002-07:002012-09-24T14:26:58.562-07:00The Reason I'll never use MongoDB againMongoDB has been getting lots of mixed reviews on Hacker News.<br />
<br />
<a href="http://pastebin.com/raw.php?i=FD3xe6Jt">http://pastebin.com/raw.php?i=FD3xe6Jt</a>
<br />
<br />
<a href="http://diegobasch.com/ill-give-mongodb-another-try-in-ten-years">http://diegobasch.com/ill-give-mongodb-another-try-in-ten-years</a>
<br />
<br />
<a href="http://svs.io/post/31724990463/why-i-migrated-away-from-mongodb">http://svs.io/post/31724990463/why-i-migrated-away-from-mongodb</a>
<br />
<br />
I also have had a particularly poor experience with MongoDB...<br />
<br />
A few months ago, I met some nice people from 10Gen. They gave me a a MongoDB mug.<br />
<br />
Now after moderate use with a high quality brand of tea (<a href="http://www.barrystea.ie/">http://www.barrystea.ie/</a>) and a industry standard version of a dishwasher (<a href="http://www.siemens-home.co.uk/our-products/dishwashers.html">http://www.siemens-home.co.uk/our-products/dishwashers.html</a>) there have been some disturbing results:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihVtxsQX9kevnRctddErAqbQ7eZ3w2Ql6ZUXK6FKiSOJjkuRRSX8u_2U5_ZQp8A_7tz8NelFFjzUffZfi874lWsy2ykH8yZEvzo052GwpKtgoqluL34JE0ArsGz19LhClac1yObBIuzenN/s1600/2012-09-24+21.12.24.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihVtxsQX9kevnRctddErAqbQ7eZ3w2Ql6ZUXK6FKiSOJjkuRRSX8u_2U5_ZQp8A_7tz8NelFFjzUffZfi874lWsy2ykH8yZEvzo052GwpKtgoqluL34JE0ArsGz19LhClac1yObBIuzenN/s320/2012-09-24+21.12.24.jpg" width="240" /></a></div>
<br />
The data stored on this mug has started to fade away badly. If this is what happens to the data I can see - what about all the data in the database? Worse again - no errors were thrown (I'm running in default mode)<br />
<br />
Fearing the worst I migrated our corporate MongoDB instance to a etch-a-sketch stored in a vibration proof room.<br />
<br />
I know I could have raised a bug about this or tried to get some support but a long blog post and a quick over-reaction is a more pragmatic approach. At the very least 10Gen could send me a new mug.<br />
<br />
So if you are still using MongoDB - YOU HAVE BEEN WARNED...<br />
<br />Barryhttp://www.blogger.com/profile/02017529619785284672noreply@blogger.com2tag:blogger.com,1999:blog-8511353585132603614.post-81289920521262315172011-01-20T14:26:00.000-08:002011-01-20T14:37:19.573-08:00The Artifact per Environment Anti-Pattern<b>The Problem</b><br />
<br />
How to handle environment specific properties is a topic that seems to generate much discussion.<br />
<div><br />
</div><div><div>While initially this may seem a trivial problem as requirements grow the complexity of the solutions will also. Here are some of the requirements you might have to tackle:</div><div><ul><li>Overriding default properties</li>
<li>Dealing with properties that need to kept secret to the development team e.g. production passwords </li>
<li>Properties that need to be changed dynamically (tuned) while the app is running e.g. cache configuration</li>
<li>The addition of new environments after the original artifact has been built</li>
</ul></div></div><div>I've seen countless approaches to the problem - properties in the jndi tree, in the database, good old property files, pojo's etc. Each has its own pro's and con's and can range from simple implementations to hugely complex frameworks.</div><div><br />
<b>Not the Solution</b><br />
<br />
</div><div>One solution that is often suggested is rebuilding the artifact per environment and "baking" in the environment specific properties. This pattern very standard in Grails (<a href="http://www.grails.org/Environments">http://www.grails.org/Environments</a>) and often recommended for Maven (<a href="http://www.sonatype.com/books/maven-book/reference/profiles-sect-tips-tricks.html">http://www.sonatype.com/books/maven-book/reference/profiles-sect-tips-tricks.html</a>)</div><div><br />
</div><div>Now I'm sure there are many situations where this works perfectly well - a blunt axe can still chop a tree down! But, I believe that for many reasons its sub-optimal.. </div><div><br />
</div><div><b>The Downsides an Artifact per Environment:</b></div><div><ul><li><b>Inefficient </b>- the simple fact that do you have to rebuild the artifact for each environment is time consuming and involves repetition of effort</li>
<li><b>Risky </b>- After testing your artifact in your test environment you are then going to deploy a different artefact that was never tested to production</li>
<li><b>Unnecessary Builds</b> - If the properties change after you build the artifact - you need to build it again! </li>
<li><b>Hard to diagnose problems</b> - did some deploy the test war to production by accident? Get used to having to crack open jar's and war's to check the config.</li>
<li><b>Not compatible with Maven repositories - </b>Maven repositories work best with one version of an artifact per version number - e.g. there's only one Apache commons-collections 3.2.1. An artefact per environment breaks this.</li>
</ul><div><b>The Alternatives:</b></div><div><b><br />
</b></div><div>So what to do instead? Generally the best way to go is to externalise your properties from the artefact and then have it choose the correct properties at runtime. This is too general an area for one prescriptive approach but hopefully this article has ruled out building an artifact per environment.</div><div><br />
</div><div><b>Links:</b></div><div><br />
</div><div>Some ways to load properties from locations dependent on system variables in Spring </div><div><a href="http://stackoverflow.com/questions/1311360/property-placeholder-location-from-another-property/1312341#1312341">http://stackoverflow.com/questions/1311360/property-placeholder-location-from-another-property/1312341#1312341</a></div><div><br />
</div><div>Externalising Grails config</div><div><a href="http://phatness.com/2010/03/how-to-externalize-your-grails-configuration/">http://phatness.com/2010/03/how-to-externalize-your-grails-configuration/</a></div><div></div><div><br />
</div></div>Barryhttp://www.blogger.com/profile/02017529619785284672noreply@blogger.com1tag:blogger.com,1999:blog-8511353585132603614.post-32376728270516828822010-12-05T05:03:00.000-08:002010-12-05T05:13:19.851-08:00Getting Flash 10.2 beta GPU acceleration working on Ubuntu 10.10 on an Acer Revo<div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;">Unloading the video rendering to the GPU is one of the main reasons a cheap low-powered box like the Revo can function as a HD video source.</div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;">This has been supported in lots of ways previously (vlc etc.) but Flash support was always a bit of a let down.</div><div style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><span class="Apple-style-span" style="color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif;"><span class="Apple-style-span" style="border-collapse: collapse; font-size: 14px; line-height: 17px;">But Flash 10.2 beta changes that. It unloads almost all the work to the GPU leaving the CPU usage very low. The difference is startling - my Revo can now play full 1080p flash video with ease.</span></span></div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><b>Here's how I set it up:</b></div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;">The full way to get flash using on an Acer Revo on ubuntu 10.10:</div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;">Install the new flash 10.2 beta:</div><pre style="background-color: #cccccc; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #333333; font-family: 'Ubuntu Mono', 'Ubuntu Beta Mono A', Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; line-height: 17px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-height: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; vertical-align: baseline; width: auto;"><code style="background-color: #cccccc; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #222222; font-family: 'Ubuntu Mono', 'Ubuntu Beta Mono A', Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;">wget http://download.macromedia.com/pub/labs/flashplayer10/flashplayer10_2_p2_32bit_linux_111710.tar.gz
tar zxvf flashplayer10_2_p2_32bit_linux_111710.tar.gz
sudo cp libflashplayer.so /usr/lib/flashplugin-installer/
</code></pre><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;">You may need to also replace flash in other locations if you have installed in multiple places (try using 'locate libflashplayer.so' for a complete list)</div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;">Then for gpu support you also need:</div><pre style="background-color: #cccccc; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #333333; font-family: 'Ubuntu Mono', 'Ubuntu Beta Mono A', Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; line-height: 17px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-height: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; vertical-align: baseline; width: auto;"><code style="background-color: #cccccc; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #222222; font-family: 'Ubuntu Mono', 'Ubuntu Beta Mono A', Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;">sudo apt-get install libvdpau1
</code></pre><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;">If you also want it working in chrome try:</div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://lifehacker.com/5705588/how-to-get-the-flash-102-beta-working-in-google-chrome" rel="nofollow" style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #dd4814; cursor: pointer; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://lifehacker.com/5705588/how-to-get-the-flash-102-beta-working-in-google-chrome</a></div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;">To verify it is working go to a high-def you-tube video and play it. While it is playing right click and select - video info. You should see "Accelerated Video Rendering" if it has worked.</div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;">These instructions worked on my Acer Revo with Ubuntu 10.10.</div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><b>Links:</b></div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://www.osnews.com/story/24092/Flash_Player_10_2_Beta_Delivers_Hardware_Acceleration_on_Linux">http://www.osnews.com/story/24092/Flash_Player_10_2_Beta_Delivers_Hardware_Acceleration_on_Linux</a></div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://blogs.adobe.com/flashplayer/2010/11/flash-player-10-2-beta.html">http://blogs.adobe.com/flashplayer/2010/11/flash-player-10-2-beta.html</a></div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;">My answer (and question!) here: </div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: small; line-height: normal;"><a href="http://askubuntu.com/questions/16172/getting-flash-10-2-gpu-acceleration-working/16283#16283">http://askubuntu.com/questions/16172/getting-flash-10-2-gpu-acceleration-working/16283#16283</a></span></div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;">This helpful thread:</div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://forums.boxee.tv/showthread.php?t=21287">http://forums.boxee.tv/showthread.php?t=21287</a></div><div style="background-color: transparent; border-bottom-width: 0px; border-collapse: collapse; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; color: #333333; font-family: 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><br />
</div>Barryhttp://www.blogger.com/profile/02017529619785284672noreply@blogger.com1tag:blogger.com,1999:blog-8511353585132603614.post-43246644352693152042010-10-05T14:38:00.000-07:002010-10-05T14:38:45.927-07:00How to build a one click deployment job with HudsonWhile there are many solutions available for automated deployment, none of them seemed quite right for our needs. After one failed attempt at a homegrown solution our team went back to the drawing board and specified our requirements:<br />
<br />
The ideal solution had to be:<br />
<br />
<ul><li><b>Easy to Use</b> - with an audience ranging from developers to business analysts the solution needed to be intuitive and easy to explain.</li>
<li><b>Modular </b>- Things change if we changed app server or SCM we wanted only minimal changes to the tool. This also useful for testing parts of the process in isolation.</li>
<li><b>Not tied to the build tool or process of the deployable.</b> Once I've built the artifact, I don't want anything to do with its build config - that's right I don't want to look at its pom or build.xml. When working with multiple teams with differing build approaches, this is a must.</li>
<li><b>One stop shop - </b>We want the ability to deploy any of our artifacts from one place.</li>
<li><b>No Magic</b> - The worst thing that can happen with an automated approach is that when it fails no-one knows why. We wanted know what was happening during all steps of the process.</li>
<li><b>Auditable</b> - We needed to know who deployed what, to where and when</li>
<li><b>Secure</b> - Can I restrict who deploys what to where?</li>
<li><b>Simple</b> - We're lazy and code costs - the solution should contain as little custom code as possible.</li>
<li><b>Repeatable - </b>The tool should deploy any artifact to anywhere but some deployments are used over and over again e.g. latest snapshot to the systest environment. Repeating these builds should be simple.</li>
</ul><br />
As with most things there is no silver bullet but the approach below worked very well for us.<br />
<br />
<b>Step 1. Build a simple solution you can call from the command line</b><br />
<br />
Build the a bare minimum solution that works from the command line. Don't think about GUI's, security or anything else. Do think about what the minimum set of inputs are. e.g. enough to identify the deployable and the target server, no more and no less. For us this consisted of three very simple Groovy scripts:<br />
<br />
<ul><li>The first simply took the artifact id and version, constructed the correct url to our Maven Repository and downloaded the correct deployable. </li>
<li>The second script pushed the deployable to the remote server. </li>
<li>The third took the deployable and ran the actual deployment to the app server. </li>
</ul>Each step was extremely simple, logged exactly what it was doing and could be tested in isolation. We then wrapped the three scripts in one master script that called each in turn. Through this approach we now had the means to deploy any artifacts in our maven repository to any of our servers. By using a command line compatible approach you leave your options wide open for calling the job from almost anywhere. Tools to help with this step come included with most Application servers or see Cargo for a catch all solution.<br />
<br />
<b>Step 2. Add the command line solution as a parameterised job in Hudson</b><br />
<br />
<b></b>Hudson already provides great security and auditing abilities and it seemed like a natural fit. We used a parametrised build to pass the necessary parameters to the scripts: <a href="http://wiki.hudson-ci.org/display/HUDSON/Parameterized+Build">http://wiki.hudson-ci.org/display/HUDSON/Parameterized+Build</a><br />
<br />
We used drop-down fields for target servers and group id's leaving the artifact id and version as free text fields. Turning on Hudson security ensures an audit trail and if necessary the job can be locked down to certain users only. Hudson also gives you a simple gui that anyone can use.<br />
<br />
<b>Step 3. Enhance the Hudson Job with a Groovy Post Build step.</b><br />
<br />
Secret sauce... While you now have a fully working solution there are some things that can be improved. I had promised one click deployments and also the Hudson gui lacks in some areas -To improve this use the Hudson Groovy Post build plugin: <a href="http://wiki.hudson-ci.org/display/HUDSON/Groovy+Postbuild+Plugin">http://wiki.hudson-ci.org/display/HUDSON/Groovy+Postbuild+Plugin</a><br />
<br />
Configure a post build step to add a badge to each build detailing what was deployed, by whom and to where. Then you using the passed in parameters you can construct a hudson url that will repeat the same deployment job again. e.g. <span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-family: 'Courier New', Courier, monospace; font-size: 13px; line-height: 16px; white-space: pre;">http://myhudson-server/job/myDeploymentJob/buildWithParameters?Artifact=website2&Version=1.5-SNAPSHOT&TargetServer=SystemTestBox4</span> Add this url to the build badge too. By creating bookmarks with this url you now have truly "one click" deployments. These url's can also be easily sent non-technical users - e.g. by providing to the test team they can pull down the latest build for testing whenever is convenient.<br />
<br />
<b>Conclusion:</b><br />
<br />
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">After a lot of thought, I feel we have come up with a solution that ticks all the boxes. It works well for us and after over 1000 deployments to both test and production systems I'm happy to say it's a huge success. Good luck with your approach and let me know how it goes in the comments.</div>Barryhttp://www.blogger.com/profile/02017529619785284672noreply@blogger.com3tag:blogger.com,1999:blog-8511353585132603614.post-572353320135744062009-10-04T08:59:00.001-07:002009-10-04T09:47:18.453-07:00Mockito 1.8 - new useful featuresI was once a happy <a href="http://easymock.org/">EasyMock</a> user. If asked, I think I would have even questioned the need for a new mocking framework – EasyMock did it all, didn’t it?<br />
But after using <a href="http://mockito.org/">Mockito</a> for a short while I was impressed by its efficiency and ease of use. The key features for me were its simple and intuitive API and the way any Mock object will return sensible defaults for all of its methods – allowing you to concentrate on the behaviour of the methods you care about.<br />
The framework continues to improve incrementally with each release. This post gives a quick view of two of the most useful new features in Mockito 1.8<br />
<h2></h2><h2>BDD-Style Language Supported Natively</h2>BDD (<a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">Behaviour Driven Development</a>) is rapidly becoming mainstream. Standard BDD conventions recommend the use of given-when-then comments in your tests. This allows improved readability by giving clear delineation between test setup, execution and assertions. <br />
Mockito’s choice of method names previously were in conflict with these BDD conventions. Version 1.8 allows you to stick with the BDD conventions while also remaining backward compatible will older Mockito tests. <br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; height: 270px; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 100.03%;"><div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: blue;">import</span> <span style="color: blue;">static</span> org.mockito.BDDMockito.*;</pre><pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum2" style="color: #606060;"> 2:</span> </pre><pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum3" style="color: #606060;"> 3:</span> Seller seller = mock(Seller.<span style="color: blue;">class</span>);</pre><pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum4" style="color: #606060;"> 4:</span> Shop shop = <span style="color: blue;">new</span> Shop(seller);</pre><pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum5" style="color: #606060;"> 5:</span> </pre><pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum6" style="color: #606060;"> 6:</span> <span style="color: blue;">public</span> <span style="color: blue;">void</span> shouldBuyBread() <span style="color: blue;">throws</span> Exception {</pre><pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum7" style="color: #606060;"> 7:</span> <span style="color: green;">//given </span></pre><pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum8" style="color: #606060;"> 8:</span> given(seller.askForBread()).willReturn(<span style="color: blue;">new</span> Bread());</pre><pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum9" style="color: #606060;"> 9:</span> </pre><pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum10" style="color: #606060;"> 10:</span> <span style="color: green;">//when</span></pre><pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum11" style="color: #606060;"> 11:</span> Goods goods = shop.buyBread();</pre><pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum12" style="color: #606060;"> 12:</span> </pre><pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum13" style="color: #606060;"> 13:</span> <span style="color: green;">//then</span></pre><pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum14" style="color: #606060;"> 14:</span> assertThat(goods, containBread());</pre><pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum15" style="color: #606060;"> 15:</span> } </pre><br />
</div><br />
</div><br />
<h2>Capturing arguments</h2><br />
Mockito has always supported a wide range of matchers to allow verification that mocked methods are invoked with the expected arguments. However sometimes (especially when dealing with legacy code) this can limit the checks you can do without the overhead of writing a custom matcher. <br />
<br />
<br />
Version 1.8 introduces new functionality to allow you to capture and store the arguments passed the mocked methods. Standard jUnit assertions can then be applied to the captured arguments. Over reliance on capturing arguments would be a code smell in my opinion as most well abstracted code should not need to do this. However for testing legacy code and interactions with outside systems ArgumentCaptors can be very useful. <br />
<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"><br />
<div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><br />
<pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum1" style="color: #606060;"> 1:</span> ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.<span style="color: blue;">class</span>);</pre><pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum2" style="color: #606060;"> 2:</span> verify(mock).doSomething(argument.capture());</pre><pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum3" style="color: #606060;"> 3:</span> assertEquals(<span style="color: #006080;">"John"</span>, argument.getValue().getName())</pre><br />
</div></div><br />
<h2>More Info…</h2><br />
<br />
Downloads and more information can be found at <a href="http://mockito.org/">mockito.org</a>. For maven users – simply add the following dependency to your pom:<a href="http://www.blogger.com/post-edit.g?blogID=8511353585132603614&postID=57235332013574406" name="Mockito_1.8.0"></a><br />
<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"><br />
<div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><br />
<pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: blue;"><</span><span style="color: maroon;">groupId</span><span style="color: blue;">></span>org.mockito<span style="color: blue;"></</span><span style="color: maroon;">groupId</span><span style="color: blue;">></span></pre><pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum2" style="color: #606060;"> 2:</span> <span style="color: blue;"><</span><span style="color: maroon;">artifactId</span><span style="color: blue;">></span>mockito-all<span style="color: blue;"></</span><span style="color: maroon;">artifactId</span><span style="color: blue;">></span></pre><pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: blue;"><</span><span style="color: maroon;">version</span><span style="color: blue;">></span>1.8.0<span style="color: blue;"></</span><span style="color: maroon;">version</span><span style="color: blue;">></span> </pre><br />
</div><br />
</div>Barryhttp://www.blogger.com/profile/02017529619785284672noreply@blogger.com4tag:blogger.com,1999:blog-8511353585132603614.post-66734506269979059252009-10-04T08:03:00.001-07:002009-10-04T08:03:43.769-07:00The first postFirst post - more soon!Barryhttp://www.blogger.com/profile/02017529619785284672noreply@blogger.com0