tag:blogger.com,1999:blog-65992868365934546412024-02-25T23:13:34.677+02:00Groovy and GrailsBlog is created in order to make learning of Groovy/Grails easier. It contains some common mistakes made by beginners and appropriate solutions for each issue. Hope someone will find it useful.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.comBlogger27125tag:blogger.com,1999:blog-6599286836593454641.post-68754373023024859842009-08-25T15:17:00.003+03:002009-08-25T15:33:45.885+03:00JasperReports and Weblogic deployment issueHello everyone,<br /><br />Recently I added dependency to <a href="http://jasperforge.org/website/jasperreportswebsite/trunk/index.html?group_id=252">Jasper Reports</a> 3.5.2 and my deployment on <a href="http://www.oracle.com/bea/index.html">Weblogic</a> 10.3 failed with exception similar to listed below<br /><blockquote style="font-weight: bold;">java.lang.ClassCastException: weblogic.xml.jaxp.RegistryDocumentBuilderFactory</blockquote>As far as I discoved later there can be 2 possible reasons for that. Jasper Reports has dependencies to <span style="font-weight: bold;">xerces-impl</span> and <span style="font-weight: bold;">xml-apis</span> which can cause conflict with libraries already included in Weblogic. For more details visit appropriate <a href="http://forum.springsource.org/archive/index.php/t-22597.html">link</a>.<br /><br />Therefore correct appropriate <span style="font-weight: bold;">pom.xml</span> in order to exclude mentioned dependencies:<br /><blockquote><pre><br /> < dependency ><br /> < groupid > jasperreports </ groupid ><br /> < artifactid > jasperreports </ artifactid ><br /> < exclusions ><br /> < exclusion ><br /> < groupid > xerces </ groupid ><br /> < artifactid > xercesImpl </ artifactid ><br /> </ exclusion ><br /> < exclusion ><br /> < groupid > xml-apis < /groupid ><br /> < artifactid > xml-apis < /artifactid ><br /> </ exclusion ><br /> < /exclusions ><br /> </ dependency ><br /></pre></blockquote><br />Enjoy!Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com1tag:blogger.com,1999:blog-6599286836593454641.post-86414859716137005152009-08-12T18:20:00.002+03:002009-08-12T18:29:02.218+03:00Groovy compilation problem while creating report using Jasper ReportsSorry for so big delay in posting :)<br /><br />Recently while creating report using <a href="http://jasperforge.org/website/jasperreportswebsite/trunk/index.html?group_id=252">Jasper Reports 3.5.2</a> I faced the issue with compilation error:<br /><blockquote>java.lang.NoClassDefFoundError: org/codehaus/groovy/control/CompilationFailedException</blockquote><br />It was quiet strange cause I'm using pure Java without Groovy.<br />I found solution on somebody's <a href="http://jptarqu.blogspot.com/2008/02/mail-labels-and-letter-templates-for.html">blog.</a><br /><br />In order to solve mentioned issue simple edit your <span style="font-weight: bold;">jrxml template</span> and remove the <span style="font-weight: bold;">language="groovy"</span> attribute from <span style="font-weight: bold;">jasperReport</span> node.<br /><br />Enjoy!Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com75tag:blogger.com,1999:blog-6599286836593454641.post-16271386451619083102009-05-14T23:02:00.004+03:002009-05-14T23:10:07.566+03:00Ganttzilla - online MPP, MPX, Planner documents viewerHello everyone.<br /><br />Finally got time to post some new information and it is very pleasant to me. <br />Our product, <a href="http://www.ganttzilla.com"><span style="font-weight:bold;">Ganttzilla</span></a> - online MPP, MPX, Planner documents viewer, finally launched! <br /><a href="http://www.ganttzilla.com"><span style="font-weight:bold;">Ganttzilla</span></a> is the online project plan documents viewer which supports popular Microsoft Project and Planner formats. Using it You can view or share your <span style="font-weight:bold;">Gantts</span> with anyone using just Web Browser. Now we are only beta version but hope to improve it in the future. Will be very grateful for any comments/remarks/criticism, even bugs :) <br /><br /><span style="font-weight:bold;">Enjoy!</span>Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com23tag:blogger.com,1999:blog-6599286836593454641.post-40649831361502388602009-03-09T23:31:00.005+02:002009-03-09T23:52:27.255+02:00Grails configuration issueAs far as You know Grails offers <a href="http://www.grails.org/Configuration">many solutions</a> for configuration of <a href="http://www.grails.org/">Grails</a> application. But most of the configuration is handled by the <strong><span style="font-family:courier new,courier;">Config.groovy</span></strong> file in <strong><span style="font-family:courier new,courier;">grails-app/conf</span></strong>. I used standard configurations created by default and simply added mail settings in the end of the file as was described in one of my <a href="http://grails-groovy.blogspot.com/2009/02/grails-mail-plugin-usage.html">previous posts</a>. But when I tried to read, for instance, <strong>grails.serverURL</strong> property using <strong><span style="font-family:courier new,courier;">grailsApplication.config</span></strong> at controller's layer (and even using <strong><span style="font-family:courier new,courier;">ConfigurationHolder</span></strong> at service layer) I've got empty string at <a href="http://grails-groovy.blogspot.com/2009/02/grails-reading-configuration-at-runtime.html">runtime</a>. Part of my <strong><span style="font-family:courier new,courier;">Config.groovy</span></strong> file is listed below:<br /><blockquote><pre>environments {<br /> development {<br /> grails.serverURL = "http://localhost:8080"<br /> }<br />}<br /><br />// Some other configuration.<br /><br />grails {<br /> mail {<br /> host = "smtp.gmail.com"<br /> port = 465<br /> username = "youracount@gmail.com"<br /> password = "yourpassword"<br /> props = ["mail.smtp.auth":"true"] <br /> }<br />}</pre></blockquote><br />I was quiet confused cause I still could read configuration not connected with <a href="http://www.grails.org/">grails</a>, for instance, log4j settings. <br />As I discovered later problem lied in fact that using <strong><span style="font-family:courier new,courier;"> grails { </span></strong>(and open bracket) rewrited all previous settings concerning <a href="http://www.grails.org/">grails</a>. So one of the correct solution might be:<br /><blockquote><pre>environments {<br /> development {<br /> grails.serverURL = "http://localhost:8080"<br /> grails.mail.host ="smtp.gmail.com"<br /> grails.mail.port = 465<br /> grails.mail.username = "youracount@gmail.com"<br /> grails.mail.password = "yourpassword"<br /> grails.mail.props = ["mail.smtp.auth":"true"]<br /> }<br />}</pre></blockquote><br />In this case settings are added not rewrited. Don't repeat somebody's mistakes. Enjoy!Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com1tag:blogger.com,1999:blog-6599286836593454641.post-43029101059561756502009-03-09T23:12:00.008+02:002009-03-09T23:31:20.818+02:00Grails HTTPS problemToday I secured some pages in <a href="http://grails.org/">Grails</a> application using <a href="http://en.wikipedia.org/wiki/HTTPS">HTTPS</a>. But when I tried to start application with using of a generated <a href="http://en.wikipedia.org/wiki/Key_%28cryptography%29">key</a> store and <a href="http://en.wikipedia.org/wiki/SSL">SSL</a> certificate for <a href="http://en.wikipedia.org/wiki/HTTPS">HTTPS</a>:<br /><blockquote><strong><span style="font-family:courier new,courier;">grails run-app-https</span></strong></blockquote>I've got an exception:<br /><blockquote>Could not execute method PluginManagerHolder.<br />No such property: PluginManagerHolder for class: RunAppHttps_groovy</blockquote>And application terminated immediately.<br />As I discovered later <a href="http://www.nabble.com/Problem-with-%22grails-run-app-https%22-td20511282.html">problem</a> lied in <span style="font-weight: bold;">RunAppHttps.groovy</span> script which is located under <strong><span style="font-family:courier new,courier;">GRAILS_HOME\scripts</span></strong>. You have to add missing import in it:<br /><blockquote>import org.codehaus.groovy.grails.plugins.PluginManagerHolder</blockquote><br />That solved the problem. Enjoy!Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-29598934595258922652009-03-08T23:57:00.013+02:002009-03-09T00:38:33.123+02:00Grails GSP concatenation nuanceWhile working with <a href="http://docs.codehaus.org/display/GRAILS/GSP+Tag+Reference">GSP</a> it is a common situation to perform actions with strings, domain objects or other classes. Recently I faced the simple situation where I needed to dynamically build full file name (with file extension) in order to allow user to download it from file system. In my simple <a href="http://docs.codehaus.org/display/GRAILS/GSP+Tag+Reference">GSP</a> I created the code similar to listed below:<br/><br /><textarea rows="2" cols="40" readonly="true"><g:set var="documentFileFullName" value="${document.fileName + "." + document.fileType.name().toLowerCase()}/"></textarea><br/><br />I use concatenation of strings in order to build full file name. But at runtime exception occurred which was very strange and gave me no tip for possible mistake made. As I discovered later in my example You can not use dot in double quotes (<span style="font-weight: bold;">"."</span>) cause <a href="http://www.grails.org/">Grails</a> wants to interprete expression in them and fails.<br />Therefore You can solve mentioned situation in two ways:<ul><li>Use dot in single quotes (<span style="font-weight: bold;">'.'</span>). In that case correct solution might be:<br/><br /><textarea rows="2" cols="40" readonly="true"><g:set var="documentFileFullName" value="${document.fileName + '.' + document.fileType.name().toLowerCase()}/"></textarea></li><br /><li>Move mentioned logic to some separate class (for instance, let's call it DocumentFileNameBuilder) and call it as it listed below:<br/><br /><textarea rows="5" cols="40" readonly="true"><%@ page import="com.company.project.core.ui.url.DocumentFileNameBuilder" %><g:set var="documentFileFullName" value="${new DocumentFileNameBuilder().build(document)}"/></textarea><br /></li></ul>Simple stupid issue solved :)Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com4tag:blogger.com,1999:blog-6599286836593454641.post-53635194496368030392009-03-08T00:18:00.017+02:002009-03-09T23:30:27.532+02:00Grails ReCapthcha Plugin custom themingRecently I got acquainted with <a href="http://www.grails.org/ReCaptcha+Plugin">Grails ReCaptcha Plugin</a>, which is very useful for integration with <a href="http://recaptcha.net/">ReCaptcha service</a>. All steps for its installation and basic usage are described <a href="http://www.grails.org/ReCaptcha+Plugin">her</a><a href="http://www.grails.org/ReCaptcha+Plugin">e</a>.<br />But one issue which was not covered in details and was not so easy personally for me is customization of <a href="http://recaptcha.net/">ReCaptcha</a> look'n'feel. In other words how to create own custom theme instead of using few standards (red, white, blackglass and clean). I've looked through <a href="http://recaptcha.net/apidocs/captcha/client.html">ReCaptcha API Documentation</a> and <a href="http://wiki.recaptcha.net/index.php/Theme">Wiki</a>, investigated <a href="http://recaptcha.net/fastcgi/demo/customtheme">simple demo</a>, and as a result created simple example for creation of custom theming.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw7zSGFZpbDudJ3TbnJkK31EFXBfSI5BpUbe605NAyNEsCWz0Z3pz5DvtKt7NVu_vTgaBhTdoI4KIroE5BvIJLOAplUcw8AzjWZsaBDc5Q_kU1YpVr2-NoY6ztLNsXcTTFbHBA4WOA3Rs/s1600-h/1.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 482px; height: 342px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw7zSGFZpbDudJ3TbnJkK31EFXBfSI5BpUbe605NAyNEsCWz0Z3pz5DvtKt7NVu_vTgaBhTdoI4KIroE5BvIJLOAplUcw8AzjWZsaBDc5Q_kU1YpVr2-NoY6ztLNsXcTTFbHBA4WOA3Rs/s400/1.JPG" alt="" id="BLOGGER_PHOTO_ID_5310585433379045730" border="0" /></a><br /><span style="font-weight: bold;">Pay attention</span>:<br />1. Create div with, for instance, <span style="font-weight: bold;">recaptcha_widget</span> identifier which is not displayed. After the <a href="http://recaptcha.net/">ReCaptch</a><a href="http://recaptcha.net/">a </a>theming code will be fully loaded, it will make the div visible. You <span style="font-weight: bold;">don't have</span> to make it visible by hands.<br />2. Place mentioned div identified to appriate attribute of recaptcha tag (<span style="font-weight: bold;">custom_theme_widget="recaptcha_widget"</span>).<br />3. Create div for recaptcha image, it has to be <span style="font-weight: bold;">empty</span> and has <span style="font-weight: bold;">fixed</span> size.<br />4. Create text field for response and some additional divs for errors, or for recaptcha options (reloading f recaptcha, changing it to audio, help, etc.). Tag identifiers and names <span style="font-weight: bold;">mus</span>t match!<br />5. As an addition You can download standard <a href="http://recaptcha.net/">ReCaptcha</a> images and integrate them into Your theme.<br />As a result all these divs, text field, links and images can be connected to CSS classes and are easy customizable. Also You can use Grails tags, for instance, to render links. Enjoy!<br /><br /><span style="font-weight: bold;">P.S.</span> Sorry for using image - don't know how to ignore HTML tags, <a href="http://www.mysysad.com/2008/06/show-html-tags-within-blogger-post.html">textarea is not a good solution</a>.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com1tag:blogger.com,1999:blog-6599286836593454641.post-48365703684876906552009-02-18T23:14:00.007+02:002009-02-18T23:44:47.426+02:00Grails: reading configuration at runtimeAs far as You know some <a href="http://grails.org/Config">basic configuration</a> in Your Grails application is located in <a href="http://grails.org/Config">Config.groovy</a> (under grails-app/conf folder). Often it is very useful to access data from it at runtime. To do that You have to use <a href="http://grails.org/doc/1.0.x/api/org/codehaus/groovy/grails/commons/ConfigurationHolder.html">org.codehaus.groovy.grails.commons.ConfigurationHolder</a>. For example, let's read SMTP properties from <a href="http://grails-groovy.blogspot.com/2009/02/grails-mail-plugin-usage.html">one of the previous posts</a>.<br /><br /><span style="font-weight: bold;">Config.groovy</span>:<br /><blockquote><pre><span style="color: rgb(153, 0, 0);">// Some simple SMTP configuration.</span><br />grails {<br /> mail {<br /> host = "smtp.gmail.com"<br /> port = 465<br /> username = "youracount@gmail.com"<br /> password = "yourpassword"<br /> props = ["mail.smtp.auth":"true"]<br /> }<br />}</pre></blockquote><br />Some service, for instance <span style="font-weight: bold;">Email service</span>:<br /><blockquote><pre><span style="color: rgb(153, 0, 0);">// Using <a href="http://grails-groovy.blogspot.com/2009/02/groovy-import-aliasing.html">import aliasing.</a></span><br />import org.codehaus.groovy.grails.commons.ConfigurationHolder <br />as confHolder<br /><br />class EmailService {<br /><br /> def sendEmail() {<br /> <span style="color: rgb(153, 0, 0);">// Reading property by name.</span><br /> def username = confHolder.config.grails.mail.username<br /> }<br /><br />}</pre></blockquote><br />As You can see its very simple. In order to have access to <a href="http://grails.org/Config">Grails configuration</a> from controllers or tags use <a href="http://grails.org/doc/1.0.x/api/org/codehaus/groovy/grails/commons/GrailsApplication.html">grailsApplication</a>: in our case <span style="font-weight:bold;">grailsApplication.config.grails.mail.username</span>. Enjoy!Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-14506269589109812482009-02-18T22:53:00.003+02:002009-02-18T23:13:16.705+02:00Groovy import aliasingOne of the <a href="http://groovy.codehaus.org/">Groovy</a> features I've discovered recently is <a href="http://docs.codehaus.org/display/GROOVY/Static+Import+Usage"><span style="font-weight: bold;">"import aliasing"</span></a>. For instance, You have two classes with the <span style="font-weight: bold;">same</span> name located in two different packages. When You would like to use them together there will be conflict and to resolve it You have to use one of the mentioned classed with full package name. If someone faced such situation You know how inconvenient it is. <a href="http://groovy.codehaus.org/">Groovy</a> helps to solve such situation using <span style="font-weight: bold;">"import aliasing"</span>: there is an opportunity to set an alias for every import in Your class. For instance, You want to use two different <span style="font-weight: bold;">Calendar</span> classes. Let's create alias for own <span style="font-weight: bold;">Calendar</span> entity:<br /><br /><blockquote><pre>package com.mycompany.myorganization.core.service<br /><br />import java.util.Calendar<br />import com.mycompany.myorganization.core.domain.Calendar <br /><span style="color: rgb(153, 0, 0);">as MyCalendar</span><br /><br />// Some other imports.<br /><br />class UserService {<br /> <span style="color: rgb(153, 0, 0);">// Using both Calendars.<br /> // Exampe of using own Calendar entity:<br /> // MyCalendar myCalendar = new MyCalendar()</span><br />}</pre></blockquote><br />Another situation when You can use <span style="font-weight: bold;">aliasing</span> is long package names.<br />That's all. Enjoy it!<br /><span style="font-weight: bold;"></span>Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com7tag:blogger.com,1999:blog-6599286836593454641.post-13534745177868241552009-02-16T10:04:00.007+02:002009-02-16T10:34:45.111+02:00Unit testing: testing controller using Testing PluginIn previous posts (<a href="http://grails-groovy.blogspot.com/2009/02/unit-testing-testing-domain-entity.html">Unit testing: testing domain entity using Testing Plugin</a> and <a href="http://grails-groovy.blogspot.com/2009/02/unit-testing-testing-service-in-3_08.html">Unit testing: testing service in 3 different ways (part III)</a>) we covered how to write unit test for domain entity and for simple service using <a href="http://grails.org/Testing+Plugin">Grails Testing Plugin</a>. In this post I would like to show You how to write a simple unit test for controller using special <span style="font-weight: bold;">mock*()</span> function and special unit test case - <span style="font-weight: bold;">mockController()</span> and <span style="font-weight: bold;">ControllerUnitTestCase</span>. Suppose that we have simple <span style="font-weight: bold;">User</span> controller. In our example we will test <span style="font-weight: bold;">update_account_information method</span>. Let's have a look in details:<br /><br /><blockquote><pre>class UserController {<br /><br /> <span style="color: rgb(153, 0, 0);">// Controller uses user service<br /> // by dynamic injection.</span><br /> def userService<br /><br /> def update_account_information = {<br /> User user = userService.retrieveUserById(<br /> session.user.id)<br /> user.email = params.email<br /> user.firstName = params.firstName<br /> user.lastName = params.lastName<br /><br /> try {<br /> userService.saveUser(user)<br /><br /> render(view: "profile", <br /> model: [user: user, <br /> accountInformationUpdateMessageCode:<br /> "User.account.information.updated"<br /> ])<br /> }<br /> catch (InvalidUserException e) {<br /> render(view: "profile", <br /> model: [user: user])<br /> }<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);">// Some other methods.</span><br /><br />}</pre></blockquote><br /><br />As You can see - nothing complicated. Let's create a simple unit test using <a href="http://grails.org/Testing+Plugin">Grails Testing Plugin</a>:<br /><br /><blockquote><pre>class UserControllerTests extends <span style="color: rgb(153, 0, 0);">ControllerUnitTestCase</span> {<br /><br /> def controller<br /><br /> UserControllerTests() {<br /> <span style="color: rgb(153, 0, 0);">// Will test User controller class.<br /> // Do not forget to call super method at first.<br /> // It will create test for specific controller.</span><br /> super(UserController)<br /> }<br /><br /> void setUp() {<br /> <span style="color: rgb(153, 0, 0);">// Do not forget to call super method at first.</span><br /> super.setUp()<br /> <br /> <span style="color: rgb(153, 0, 0);">// You have to initialize controller manually,<br /> // There is no dynamic injection.</span><br /> controller = new UserController()<br /><br /> <span style="color: rgb(153, 0, 0);">// Initialise the user service.</span><br /> def userService = new UserService()<br /> <br /> controller.userService = userService<br /> }<br /><br /> void testUpdateAccountInformationSuccess() {<br /> <span style="color: rgb(153, 0, 0);">// Mocking domain classes.</span><br /> def user = new User(id: 1L, <br /> email: "taras.matyashovsky@gmail.com", <br /> firstName: "Taras", lastName: "Matyashovsky", <br /> password: "some hash")<br /> mockDomain(User, [user])<br /><br /> <span style="color: rgb(153, 0, 0);">// Putting user into session.</span><br /> controller.session.user = user<br /><br /> <span style="color: rgb(153, 0, 0);">// Setting controller's parameters.</span><br /> controller.params.email = <br /> "taras.matyashovsky@gmail.com"<br /> controller.params.firstName = "Tarasuk"<br /> controller.params.lastName = "Matyash"<br /><br /> <span style="color: rgb(153, 0, 0);">// Testing the target method.</span><br /> controller.update_account_information()<br /><br /> <span style="color: rgb(153, 0, 0);">// Assertions.</span><br /> assertEquals "profile", renderArgs.view<br /> assertEquals user, renderArgs.model.user<br /> assertEquals "User.account.information.updated",<br />renderArgs.model.accountInformationUpdateMessageCode<br /> }<br /><br /> void testUpdateAccountInformationFailure() {<br /> <span style="color: rgb(153, 0, 0);">// Mocking domain classes.</span><br /> def user = new User(id: 1L, <br /> email: "taras.matyashovsky@gmail.com", <br /> firstName: "Taras", <br /> lastName: "Matyashovsky")<br /> mockDomain(User, [user])<br /><br /> <span style="color: rgb(153, 0, 0);">// Putting user into session.</span><br /> controller.session.user = user<br /><br /> <span style="color: rgb(153, 0, 0);">// Passing invalid parameters.</span><br /> controller.params.email = "INVALID EMAIL ADDRESS"<br /> controller.params.firstName = "Tarasuk"<br /> controller.params.lastName = "Matyash"<br /><br /> <span style="color: rgb(153, 0, 0);">// Testing the target method.</span><br /> controller.update_account_information()<br /><br /> assertEquals "profile", renderArgs.view<br /> assertEquals user, renderArgs.model.user<br /> }<br /><br />}</pre></blockquote><br /><br />Pay attention to few key points:<br /><ul><li>by using <span style="font-weight: bold;">ControllerUnitTestCase</span> the controller's <tt></tt>render method and params property work without any work on our part. This is true of all the dynamic properties and methods of the controller: <tt style="font-weight: bold;"></tt><span style="font-weight: bold;">request</span>, <span style="font-weight: bold;">response</span>, <span style="font-weight: bold;"> params</span>, <span style="font-weight: bold;">session</span>, <span style="font-weight: bold;">controllerName</span>, <span style="font-weight: bold;">redirect</span>, etc. All stuff is done by <a href="http://grails.org/Testing+Plugin">Testing Plugin</a></li><li>do not forget to call <span style="font-weight: bold;">super</span> methods - this will make sure that test will mock appropriate controller class</li></ul>That's all for now.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com1tag:blogger.com,1999:blog-6599286836593454641.post-81737748242974424002009-02-15T23:39:00.011+02:002009-02-16T00:34:33.228+02:00Grails Integration Testing: common information<a href="http://grails.org/doc/1.0.x/guide/9.%20Testing.html">Integration tests</a> differ from <a href="http://grails.org/doc/1.0.x/guide/9.%20Testing.html">unit tests</a> in that you have full access to the <a href="http://grails.org/">Grails</a> environment within the test. <a href="http://grails.org/">Grails</a> will use an in-memory <a href="http://hsqldb.org/">HSQLDB</a> database (or another configured data source, for instance <a href="http://www.mysql.com/">MySQL</a>) for integration tests and clear out all the data from the database in between each test. You have to understand that each test is wrapped into transaction which will be rolled back lately. So integration test:<br /><ul><li>will talk to database, so it will be slower than unit test<br /></li><li>will persist data to database - make sure Your test environment database setting don't point to production or development database</li></ul>A couple of helpful thoughts concerning integration tests:<br /><ol><li>You have to initialize the service class yourself, there is no dynamic injection. It is the same way as it was during unit testing.<br /></li><li>If the service has other service class inside it, You have to initialize and assign it manually. Also it is the same way as it was during unit testing.<br /></li><li>Sometimes it is useful to flush session in order to persist to database immediately - else You might get weird thing like no "id" for the supposedly saved domain object or deleted objects would be not deleted. How to do that? It's very easy, please look at the simple example:<blockquote><pre>class DocumentServiceTests extends GroovyTestCase {<br /><br /> def documentService<br /><br /> <span style="color: rgb(153, 0, 0);">// Dynamic injection of session factory.<br /></span> def sessionFactory<br /><br /> void setUp() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // You have to initialize service, <br /> // there is no dynamic injection.</span><br /> documentService = new DocumentService()<br /> } <br /><br /> void testSomething() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Some logic. For instance, <br /> // documentService.deleteDocumentById(1L).<br /> // But document is still <strong>not</strong> <br /> // deleted after execution.<br /> // You have to manually flush the session <br /> // before assertions.</span><br /> sessionFactory.currentSession.flush()<br /> sessionFactory.currentSession.clear()<br /><br /> <span style="color: rgb(153, 0, 0);">// Assertions.</span><br /> }<br /><br />}<br /><br /></pre></blockquote></li></ol><br />That's all for now.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com1tag:blogger.com,1999:blog-6599286836593454641.post-55984760246469034702009-02-11T00:19:00.007+02:002009-02-11T01:11:19.558+02:00Grails Mail plugin usageEssential feature of every web application is possibility to send emails. Traditionally when You will look through <a href="http://grails.org/doc/1.0.x/">Grails reference</a> You will find page concerning <a href="http://grails.org/Mail+from+Grails">proposals for email integration in Grails</a>. But approaches mentioned there are not perfect and their implementation in our application was quiet hard. So I decided to look for another solutions and found excellent <a href="http://grails.org/Mail+Plugin">Grails Mail Plugin</a>. You can easily install it using command:<br /><blockquote><strong><span style="font-family:courier new,courier;">grails install-plugin mail</strong></span></blockquote><br /><a href="http://grails.org/Mail+Plugin">Grails Mail Plugin</a> integration is very simple - everything You need is to dynamically inject <span style="font-weight: bold;">mail service</span> into Your service. After that You can use its <span style="font-weight: bold;">sendMail</span> method for sending email:<br /><blockquote><pre>class MyService {<br /><br /> <span style="color: rgb(153, 0, 0);">// Dynamic injection happens here.</span><br /> MailService mailService<br /><br /> def someMethod() {<br /> <span style="color: rgb(153, 0, 0);">// Some logic.</span><br /> mailService.sendMail {<br /> to "email@mail.com"<br /> from "youraccount@gmail.com"<br /> subject "Test mail"<br /> html """Hello!<br /> This is a test email. """<br /> }<br /> }<br />}</pre></blockquote>Do not forget to configure Your mail server, configuration is located in <span style="font-family: monospace;"></span><span style="font-weight: bold;">grails-app/Config.groovy</span> file. In my example it can be similar to listed below:<br /><blockquote><pre>grails {<br /> mail {<br /> host = "smtp.gmail.com"<br /> port = 465<br /> username = "youraccount@gmail.com"<br /> password = "yourpassword"<br /> props = ["mail.smtp.auth":"true", <br /> "mail.smtp.socketFactory.port":"465",<br /> "mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",<br /> "mail.smtp.socketFactory.fallback":"false"] <br />}</pre></blockquote><br />One topis is not covered - <a href="http://grails.org/doc/1.0.x/guide/9.%20Testing.html">unit and integration testing</a> of <span style="font-weight: bold;">mail service</span>. You will not believe but only thing You need is to initialise <span style="font-weight: bold;">mail service</span> in Your <a href="http://grails.org/doc/1.0.x/guide/9.%20Testing.html">integration or unit test</a> and connent it to <span style="font-weight: bold;">my service</span>. Short example:<br /><blockquote><pre>class MyServiceTests extends <span style="color: rgb(153, 0, 0);">GrailsUnitTestCase</span> {<br /><br /> MyService myService<br /><br /> void setUp() {<br /> <span style="color: rgb(153, 0, 0);">// Do not forget to call super method at first.</span><br /> super.setUp()<br /><br /> <span style="color: rgb(153, 0, 0);">// Initialize the my service.</span><br /> userService = new UserService()<br /> <span style="color: rgb(153, 0, 0);">// Initialize the mail service and <br /> // connect it to my service</span><br /> userService.mailService = new MailService() <br /> }<br /><br /> <span style="color: rgb(153, 0, 0);">// Some tests.</span><br /><br />}</pre></blockquote>That's all concerning <a href="http://grails.org/Mail+Plugin">Grails Mail Plugin</a>, hope You enjoyed it.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com3tag:blogger.com,1999:blog-6599286836593454641.post-58966440046198434812009-02-10T23:37:00.005+02:002009-02-11T00:10:47.889+02:00Grails combining integration and unit testingYesterday I faced the situation when in <a href="http://grails.org/doc/1.0.x/guide/9.%20Testing.html">integration test</a> I needed some logic to be mocked and to be executed in particular way. Therefore I asked a question about possibility of combining <a href="http://grails.org/doc/1.0.x/guide/9.%20Testing.html">integration and unit testing</a> approaches. In someone is interested - please review mentioned situation in details. Do not forget that is based on <a href="http://grails.org/Testing+Plugin">Grails Testing Plugin</a>, so if You are new to it please review some of my previous posts.<br /><br />I have <span style="font-weight: bold;">FileService</span> which has methods for saving/retrieving/deleting files in local file system. Files are distinguished by<span style="font-weight: bold;"> guid</span>, and full path to the file is generated using <span style="font-weight: bold;">storage root</span> property plus mentioned <span style="font-weight: bold;">guid</span>. <span style="font-weight: bold;">Storage root</span> property is hard coded into the service (<span style="font-style: italic;">I know that is not the best solution but quiet comfortable for me</span>). Described logic is listed below:<br /><blockquote><pre>class FileService {<br /><br /> <span style="color: rgb(153, 0, 0);">// File system's storage root. Hardcoded. </span><br /> String storageRoot = "C:\\"<br /><br /> def retrieveFullPath(String guid) {<br /> "${storageRoot}\\${guid}.pdf"<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);">// Some other methods for <br /> // saving/retrieving/deleting files.</span><br /><br />}</pre></blockquote><br />Also I have other service called <span style="font-weight: bold;">Project Service</span> in which <span style="font-weight: bold;">File Service</span> is dynamically injected using <a href="http://www.springsource.org/">Spring</a>. It uses its <span style="font-weight: bold;">retrieveFullPath</span> method. Let's look more concrete:<br /><blockquote><pre>class ProjectService {<br /><br /> def fileService<br /> <br /> def retrieveProject(String guid) {<br /> <span style="color: rgb(153, 0, 0);">// Some logic.</span><br /> def filePath = fileService.retrieveFullPath(guid)<br /> <span style="color: rgb(153, 0, 0);">// Some logic.</span><br /> }<br /> <br /> <span style="color: rgb(153, 0, 0);">// Some other methods.</span><br />}</pre></blockquote><br />Everything looking good and I decided to write simple <a href="http://grails.org/doc/1.0.x/guide/9.%20Testing.html">integration test</a>. But faced with the first question: in my test I need test file to be stored somewhere in the test folder of the application. But when I will use it's <span style="font-weight: bold;">guid</span>, <span style="font-weight: bold;">file service</span> will retrieve full path according to <span style="font-weight: bold;">storage root</span> property and that path will be invalid and exception will be thrown. Therefore I decided to <span style="font-weight: bold;">mock</span> mentioned logic in order to retrieve real file which exists under test folder. Let's have a look at the test:<br /><blockquote><pre><br />class ProjectServiceTests extends <span style="color: rgb(153, 0, 0);">GrailsUnitTestCase</span> {<br /><br /> def projectService<br /><br /> void setUp() {<br /> <span style="color: rgb(153, 0, 0);">// Do not forget to call super method at first.</span><br /> super.setUp()<br /><br /> <span style="color: rgb(153, 0, 0);">// Initialise the service.<br /> // There is no dynamic injection.</span><br /> projectService = new ProjectService()<br /> }<br /><br /> void testRetrieveProject() {<br /> <span style="color: rgb(153, 0, 0);">// Loading file for test folder<br /> // using <a href="http://static.springframework.org/spring/docs/1.1.5/api/org/springframework/core/io/ClassPathResource.html">Spring's ClassPathResource</a> class.</span><br /> def fileName = <br /> new ClassPathResource("test/testfile.pdf")<br /> .getFile().getPath()<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Mocking file service not to use its storage root <br /> // and to return needed file path.<br /> // In this case file service will return<br /> // real path to the file in Your file system.</span><br /> def fileServiceMock = mockFor(FileService)<br /> fileServiceMock.demand.retrieveFullPath {<br /> String guid -><br /> return fileName<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);">// Creating a file service mock <br /> // in project service.</span><br /> projectService.fileService = <br /> (FileService) fileServiceMock.createMock()<br /><br /> <span style="color: rgb(153, 0, 0);">// Calling the target method.</span><br /> projectService.retrieveProject("testfile")<br /><br /> <span style="color: rgb(153, 0, 0);">// Some assertions.</span> <br /> }<br /><br />}</pre></blockquote><br />That's all. In listed integration test we combined some approaches from unit testing. Hope someone found it interesting.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-32642159870253264732009-02-10T00:06:00.005+02:002009-02-10T00:20:02.507+02:00Grails Testing Plugin often occurred exceptionIn previous posts (<a href="http://grails-groovy.blogspot.com/2009/02/unit-testing-testing-service-in-3_08.html">service unit testing</a> and <a href="http://grails-groovy.blogspot.com/2009/02/unit-testing-testing-domain-entity.html">domain entity unit testing</a>) I told You a lot about <a href="http://grails.org/Testing+Plugin">Grails Testing Plugin</a>, its simple usage, but have not paid necessary accent on one often occurred exception:<br /><blockquote><strong><span style="font-family:courier new,courier;">"Cannot invoke method containsKey() on null object" type="java.lang.NullPointerException"</span></strong></blockquote><br />It happens then You override <span style="font-weight:bold;">setUp(</span>) method but forget to call super method at first. So instead of writing:<br /><blockquote><pre>class SomeTests extends GrailsUnitTestCase {<br /><br /> void setUp() {<br /> <span style="color: rgb(153, 0, 0);">// Some initializations.</span><br /> }<br /><br />}</pre></blockquote><br />Call <span style="font-weight:bold;">super</span> method at first:<br /><blockquote><pre>class SomeTests extends GrailsUnitTestCase {<br /><br /> void setUp() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Call super method at first.</span><br /> super.setUp()<br /> <br /> <span style="color: rgb(153, 0, 0);"><br /> // Some initializations.</span><br /> }<br /><br />}<br /></pre></blockquote><br />That's all.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com2tag:blogger.com,1999:blog-6599286836593454641.post-64448185378667755902009-02-09T22:40:00.003+02:002009-02-09T22:50:17.043+02:00GORM 1 to 0..1 relationship issueRecently I wanted to create <a href="http://www.onlamp.com/pub/a/onlamp/2001/03/20/aboutSQL.html">one-to-one relationship</a> (1 to 0..1) not pure <a href="http://www.onlamp.com/pub/a/onlamp/2001/03/20/aboutSQL.html">1 to 1</a>. But unfortunately faced with the problem. Let's review it in details (entity <span style="font-weight: bold;">A</span> can have association with zero or only one entity <span style="font-weight: bold;">B</span>):<br /><blockquote><pre>class A {<br /> B b<br /><br /> static constraints = {<br /> b(nullable: true)<br /> }<br /><br />}<br /><br />class B {<br /> A a<br /><br /> static belongsTo = [A]<br />}</pre></blockquote><br /><a href="http://grails.org/">Grails</a> generated the database schema in such way: table <span style="font-weight: bold;">A</span> has column <span style="font-weight: bold;">b_id</span> (as it has to be), but it cannot be <span style="font-weight: bold;">nullable</span>. As You can see for <a href="http://www.onlamp.com/pub/a/onlamp/2001/03/20/aboutSQL.html">1 to 0..1</a> relationship this is a wrong behavior. I posted question on <a href="http://www.nabble.com/">Nabble forums</a> (as I recommended to everyone:) ) and received answer that mentioned problem will be fixed in <a href="http://grails.org/Roadmap">Grails 1.1</a>. For more details visit <a href="http://www.nabble.com/GORM-1-to-0..1-relationship-issue-td21900385.html">appropriate forum post</a>.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-68583138590619730042009-02-09T18:47:00.005+02:002009-02-09T18:59:39.823+02:00Grails code coverage plugin issueRecently I've installed official <a href="http://grails.org/Test+Code+Coverage+Plugin">Grails Code Coverage plugin</a> (called Cobertura). As fas as I'm using <a href="http://grails.org/">Grails 1.0.4</a> appropriate code coverage plugin version for me is <span style="font-weight: bold;">0.9</span>. You also can install it using simple <a href="http://grails.org/">Grails</a> command:<br /><blockquote><strong><span style="font-family:courier new,courier;">grails install-plugin code-coverage 0.9</span></strong></blockquote>But when I tried to use it and to generate test reports using command:<br /><blockquote><strong><span style="font-family:courier new,courier;">grails test-app-cobertura</span></strong></blockquote>I've got an exception:<br /><blockquote><strong><span style="font-family:courier new,courier;">[cobertura-report] java.lang.NoClassDefFoundError: org/apache/log4j/Category<br />[cobertura-report] Exception in thread "main"</span></strong></blockquote>Reason for that was that <a href="http://grails.org/Test+Code+Coverage+Plugin">Code Coverage plugin</a> needs <a href="http://logging.apache.org/">log4j</a> library to be present in project library folder. So when I downloaded latest version (for me it was <a href="http://logging.apache.org/log4j/1.2/download.html">1.2.15</a>) everything worked great. Enjoy using <a href="http://grails.org/Test+Code+Coverage+Plugin">Grails Code Coverage Plugin</a>!Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-21551805139776835122009-02-08T11:47:00.006+02:002009-02-08T13:28:26.181+02:00Unit testing: testing domain entity using Testing PluginIn <a href="http://grails-groovy.blogspot.com/2009/02/unit-testing-testing-service-in-3_08.html">previous post</a> we got acquainted with <a href="http://grails.org/Testing+Plugin">Grails Testing Plugin</a>. In this post we will look closer how to write unit test for domain class, especially how to easily test its constraints. As far as I mentioned <a href="http://grails.org/Testing+Plugin">Testing Plugin</a> includes a lot of <span style="font-weight: bold;">mock*()</span> methods for testing domain entities, controllers, tag libs, etc. One of such methods is <span style="font-weight: bold;"><a href="http://grails.org/Testing+Plugin">mockForConstraintsTests()</a></span> method which is very useful to check whether the constraints are behaving as you expect them to.<br />Suppose we have a simple domain class like so: <br /><br /><blockquote><pre>class User {<br /><br /> String email<br /> String firstName<br /> String lastName<br /> String password<br /> <br /> static constraints = {<br /> email(email: true, unique: true, blank: false, <br /> maxSize: 64)<br /> firstName(blank: false, minSize: 2, maxSize: 32)<br /> lastName(blank: false, minSize: 2, maxSize: 32)<br /> password(blank: false, maxSize: 128)<br /> }<br /><br /> String toString() {<br /> """User [email: ${email}, <br /> firstName: ${firstName}, <br /> lastName: ${lastName}]"""<br /> }<br /><br />}</pre></blockquote><br /><br />To test these constraints we can do the following:<br /><br /><blockquote><pre>class UserTests extends <span style="color: rgb(153, 0, 0);">GrailsUnitTestCase</span> {<br /><br /> void testUserConstraints() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Assume that we have an existing user <br /> // in the database.</span><br /> def existingUser = new User(<br /> email: "taras.matyashovsky@gmail.com", <br /> firstName: "Taras", <br /> lastName: "Matyashovsky",<br /> password: "some hash")<br /> <span style="color: rgb(153, 0, 0);">// Using mockForConstraintsTests for mocking.</span><br /> mockForConstraintsTests(User, [existingUser])<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Validation should fail if email or <br /> // first name or last name or <br /> // password properties are null.</span><br /> def user = new User()<br /> assert !user.validate()<br /> assertEquals "nullable", user.errors["email"]<br /> assertEquals "nullable", user.errors["firstName"]<br /> assertEquals "nullable", user.errors["firstName"]<br /> assertEquals "nullable", user.errors["password"]<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // So let's demonstrate the unique <br /> // and min size constraints.<br /> // Insert user with the same email <br /> // and very short first and last names.</span style="color: rgb(153, 0, 0);"><br /> user = new User(<br /> email: "taras.matyashovsky@gmail.com", <br /> firstName: "T", <br /> lastName: "M",<br /> password: "some hash")<br /> assert !user.validate()<br /> assertEquals "unique", user.errors["email"]<br /> assertEquals "minSize", user.errors["firstName"]<br /> assertEquals "minSize", user.errors["lastName"]<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // So let's demonstrate the max size constraints.<br /> // First name is too long (more than 32 symbols).</span><br /> user = new User(<br /> email: "grails-groovy@blogger.com", <br /> firstName: "TarasTarasTarasTarasTarasTarasTaras",<br /> lastName: "Matyashovsky", <br /> password: "some hash")<br /> assert !user.validate()<br /> assertEquals "maxSize", user.errors["firstName"]<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Validation should pass.</span><br /> user = new User(<br /> email: "andriy.suran@gmail.com", <br /> firstName: "Andriy", <br /> lastName: "Suran",<br /> password: "some hash")<br /> assert user.validate()<br /> }<br /><br />}</pre></blockquote><br /><br />Using errors property we can access all the properties and methods we should normally expect. We simply specify the name of the field we are interested in and the map/property access will return the name of the constraint that was violated. <a href="http://grails.org/Testing+Plugin">Testing Plugin</a> makes testing easy.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-13032002363384863892009-02-08T11:06:00.005+02:002009-02-08T13:23:53.651+02:00Unit testing: testing service in 3 different ways (part III)In previous posts (<a href="http://grails-groovy.blogspot.com/2009/02/unit-testing-testing-service-in-3.html">part I</a> and <a href="http://grails-groovy.blogspot.com/2009/02/unit-testing-testing-service-in-3_07.html">part II</a>) we tested simple service using <a href="http://groovy.codehaus.org/ExpandoMetaClass">ExpandoMetaClass</a> and <a href="http://docs.codehaus.org/display/GROOVY/Groovy+Mocks">Groovy Mocks</a>. In this post we will test simple service using new <a href="http://grails.org/Testing+Plugin">Grails Testing Plugin</a>, which will be included into <a href="http://grails.org">Grails </a>1.1. The <a href="http://grails.org/Testing+Plugin">Testing Plugin</a> targets weaknesses of mentioned approaches by providing a set of classes that make testing many of <a href="http://grails.org">Grails</a>' artifacts really easy, while providing plenty of flexibility. For installation details visit <a href="http://grails.org/Testing+Plugin">official Testing Plugin page</a>. Main features:<br /><ol><li>The core of the testing plugin is the <code style="font-weight: bold;">grails.test.GrailsUnitTestCase</code> class. So each test should extend this class instead of <code style="font-weight: bold;">groovys.util.GroovyTestCase.</code></li><li>Special <span style="font-weight: bold;">mock*()</span> methods. Using these methods ensures that any changes you make to the given classes do not leak into other tests. It also includes special <span style="font-weight: bold;">mock*()</span> methods for mocking domain objects, controllers, for testing constraints, tag libs, etc. </li></ol>Lets rewrite simple test from previous posts using the <a href="http://grails.org/Testing+Plugin">Testing Plugin</a>.<br /><br /><blockquote><pre>class DocumentServiceTests extends <span style="color: rgb(153, 0, 0);">GrailsUnitTestCase</span> {<br /><br /> def documentService<br /><br /> void setUp() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Do not forget to call super setUp()<br /> // otherwise tests will fail!.</span><br /> super.setUp()<br /><br /> <span style="color: rgb(153, 0, 0);"> <br /> // Initialize the service class, <br /> // there is no dynamic injection.</span><br /> documentService = new DocumentService()<br /> }<br /><br /> void testSaveDocumentSuccess() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Mock the domain class.<br /> // Using mockDomain method.</span><br /> def testInstances = []<br /> mockDomain(Document, testInstances)<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Testing the target method.<br /> // Testing not differs <br /> // from "real" service method call.</span><br /> documentService.saveDocument(<br /> new Document(<br /> name: "Document name", <br /> description: "Document description",<br /> lastModifiedTime: new Date(), <br /> creationTime: new Date(), <br /> revisionCount: 1L, <br /> owner: new User()))<br /> }<br /><br /> void testSaveDocumentFailure() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Mock the domain class.<br /> // Using mockDomain method.</span><br /> def testInstances = []<br /> mockDomain(Document, testInstances)<br /><br /> shouldFail(InvalidDocumentException) {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Validation will fail.</span><br /> documentService.saveDocument(<br /> new Document(<br /> name: "Document name", <br /> description: "Document description",<br /> lastModifiedTime: new Date(), <br /> creationTime: new Date(), <br /> revisionCount: 1L))<br /> }<br /> }<br /><br /> void testRetrieveDocumentByIdAndOwnerSuccess() {<br /> def owner = new User()<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Mock the domain class.<br /> // Using mockDomain method.</span><br /> def testInstances = [new Document(<br /> id: 1L, <br /> name: "Document name", <br /> description: "Document description",<br /> lastModifiedTime: new Date(), <br /> creationTime: new Date(), <br /> revisionCount: 1L, <br /> owner: owner)]<br /> mockDomain(Document, testInstances)<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Testing the target method.<br /> // Testing not differs <br /> // from "real" service method call.</span><br /> def foundDocument = <br /> documentService.retrieveDocumentByIdAndOwner(<br /> 1L, owner)<br /><br /> <span style="color: rgb(153, 0, 0);">// Assertions.</span><br /> assertNotNull foundDocument<br /> assert "Document name" == foundDocument.name<br /> assert "Document description" == foundDocument.description<br /> assert 1 == foundDocument.revisionCount<br /> }<br /><br /> void testRetrieveDocumentFailure() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Mock the domain class.<br /> // Using mockDomain method.</span><br /> def testInstances = []<br /> mockDomain(Document, testInstances)<br /><br /> shouldFail(DocumentNotFoundException) {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Method will fail as there are <br /> // no test instances to be retrieved.</span><br /> documentService.retrieveDocumentByIdAndOwner(<br /> 1L, new User())<br /> }<br /> }<br /><br />}</pre></blockquote><br />As You can see <a href="http://grails.org/Testing+Plugin">Testing Plugin</a> makes unit testing quiet easy. In this post we covered only basic features, if someone will be interested we will look closer into other special features. I recommend to use mentioned plugin instead of using <a href="http://groovy.codehaus.org/ExpandoMetaClass">ExpandoMetaClass</a> and <a href="http://docs.codehaus.org/display/GROOVY/Groovy+Mocks">Groovy Mocks</a>.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-30281817847592869532009-02-07T23:12:00.006+02:002009-02-08T13:22:27.734+02:00Unit testing: testing service in 3 different ways (part II)In <a href="http://grails-groovy.blogspot.com/2009/02/unit-testing-testing-service-in-3.html">part I</a> we got acquainted with unit testing of services based on <a href="http://groovy.codehaus.org/ExpandoMetaClass">ExpandoMetaClass</a> approach. In this part we will look on a method based on <a href="http://docs.codehaus.org/display/GROOVY/Groovy+Mocks">Groovy Mocks</a>. <a href="http://groovy.codehaus.org/">Groovy</a> has excellent built-in support for a range of mocking alternatives. Let's rewrite test from the previous post in order to use <a href="http://docs.codehaus.org/display/GROOVY/Groovy+Mocks">Groovy Mocks</a>.<br /><br /><blockquote><pre>class DocumentServiceTests extends GroovyTestCase {<br /><br /> def documentService<br /><br /> void setUp() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Initialize the service class, <br /> // there is no dynamic injection. </span><br /> documentService = new DocumentService()<br /> }<br /><br /> void testSaveDocumentSuccess() {<br /> <span style="color: rgb(153, 0, 0);">// Create the Mock support <br /> // for Document class.</span><br /> def documentMocker = new MockFor(Document)<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Demand the validate method exactly once,<br /> // and programming it to return true.</span><br /> documentMocker.demand.validate {<br /> return true<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Demand the save method exactly once,<br /> // and programming it to return true.</span><br /> documentMocker.demand.save {<br /> return true<br /> }<br /> <br /> <span style="color: rgb(153, 0, 0);">// Start using the Mock.</span><br /> documentMocker.use {<br /> documentService.saveDocument(<br /> new Document(<br /> name: "Document name", <br /> description: "Document description",<br /> lastModifiedTime: new Date(), <br /> creationTime: new Date(), <br /> revisionCount: 1L, <br /> owner: new User()))<br /> }<br /> }<br /><br /> void testSaveDocumentFailure() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Create the Mock support<br /> // for Document class.</span><br /> def documentMocker = new MockFor(Document)<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Demand the validate method exactly once,<br /> // and programming it to return false.</span><br /> documentMocker.demand.validate {<br /> return false<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);">// Start using the Mock.</span><br /> documentMocker.use {<br /> <span style="color: rgb(153, 0, 0);">// Validation will fail.<br /> // Expecting exception to be thrown.</span><br /> shouldFail(InvalidDocumentException) {<br /> documentService.saveDocument(<br /> new Document(<br /> name: "Document name", <br /> description: "Document description",<br /> lastModifiedTime: new Date(), <br /> creationTime: new Date(), <br /> revisionCount: 1L))<br /> }<br /> }<br /> }<br /><br /> void testRetrieveDocumentByIdAndOwnerSuccess() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Create the Mock support<br /> // for Document class.</span><br /> def documentMocker = new MockFor(Document)<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Demand the findByIdAndOwner method exactly once,<br /> // and programming it to return appropriate document.</span><br /> documentMocker.demand.findByIdAndOwner { <br /> Long id, User owner -><br /> return new Document(<br /> id: id, <br /> name: "Document name", <br /> description: "Document description",<br /> lastModifiedTime: new Date(), <br /> creationTime: new Date(), <br /> revisionCount: 1L, <br /> owner: owner)<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Demand the getName method exactly once,<br /> // and programming it to return appropriate name.<br /> // Needed for assertion.</span><br /> documentMocker.demand.getName {<br /> return "Document name"<br /> }<br /> <br /> <span style="color: rgb(153, 0, 0);"><br /> // Demand the getDescription method exactly once,<br /> // and programming it to return appropriate name.<br /> // Needed for assertion.</span><br /> documentMocker.demand.getDescription {<br /> return "Document description"<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Demand the getRevisionCount method exactly once,<br /> // and programming it to return appropriate name.<br /> // Needed for assertion.</span><br /> documentMocker.demand.getRevisionCount {<br /> return 1L<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);">// Start using the Mock.</span><br /> documentMocker.use {<br /> def foundDocument = <br /> documentService.retrieveDocumentByIdAndOwner(<br /> 1L, new User())<br /><br /> assertNotNull foundDocument<br /> assert "Document name" == foundDocument.name<br /> assert "Document description" == foundDocument.description<br /> assert 1 == foundDocument.revisionCount<br /> }<br /> }<br /><br /> void testRetrieveDocumentFailure() {<br /> <span style="color: rgb(153, 0, 0);"><br /> // Create the Mock support<br /> // for Document class.</span><br /> def documentMocker = new MockFor(Document)<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Demand the findByIdAndOwner method exactly once,<br /> // and programming it to return NULL.</span><br /> documentMocker.demand.findByIdAndOwner { Long id, User owner -><br /> return null<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);">// Start using the Mock.</span><br /> documentMocker.use {<br /> <span style="color: rgb(153, 0, 0);">// Document will not be found.<br /> // Exception will be thrown.</span><br /> shouldFail(DocumentNotFoundException) {<br /> documentService.retrieveDocumentByIdAndOwner(<br /> 1L, new User())<br /> }<br /> }<br /> }<br /><br />} </pre></blockquote><br /><a href="http://docs.codehaus.org/display/GROOVY/Groovy+Mocks">Groovy Mocks</a> have a lot of powerful features, especially You can mock few calls of service method, You can mock not only a tested service but also an injected service, etc. For more detailed information check resources listed below:<br /><ol><li><a href="http://docs.codehaus.org/display/GROOVY/Using+MockFor+and+StubFor">Using MockFor and StubFor</a></li><li><a href="http://docs.codehaus.org/display/GROOVY/Mocking+Static+Methods+using+Groovy">Mocking Static Methods using Groovy</a><br /></li></ol>In the next post we will rewrite mentioned test using <a href="http://grails.org/Testing+Plugin">Testing plugin</a>.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-47773263023891000242009-02-07T16:07:00.001+02:002009-02-08T13:50:13.750+02:00GORM executeQuery nuanceAs far as You know <a href="http://grails.org/doc/1.0.x/ref/Domain%20Classes/executeQuery.html">executeQuery</a> method allows the execution of <a href="http://grails.org/doc/1.0.x/guide/single.html#5.4.3%20Hibernate%20Query%20Language%20%28HQL%29" class="guide">HQL queries</a> against a domain class. In <a href="http://grails-groovy.blogspot.com/2009/02/gorm-executequery-problem.html">previous post</a> I mentioned issue concerning it in <a href="http://grails.org/">Grails</a>. To recall I will list the latest query using <span><span><a href="http://groovy.codehaus.org/">Groovy</a> shortcuts </span></span>once more:<span><span><br /><blockquote><strong><span style="font-family:courier new,courier;">DocumentRevision.executeQuery("select max(dr.versionNumber) from ${DocumentRevision.name} dr")</span></strong></blockquote></span></span> Now I want to mention one nuance more. In my query I suppose that result type would be a numeric cause versionNumber property is Long type. But result type of using executeQuery method is <span style="font-weight: bold;">always</span> <span style="font-weight: bold;">java.util.ArrayList</span>. So even if You try to retrieve maximal value of some field, or count of some records the result type will always be <span style="font-weight: bold;">ArrayList</span>. Pay attention to that fact.<br /><br />If You are not satisfied with such behavior of <a href="http://grails.org/doc/1.0.x/ref/Domain%20Classes/executeQuery.html">executeQuery</a> method please refer to <a href="http://grails.org/Hibernate+Criteria+Builder">createCriteria</a> method.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-87590274436844498192009-02-07T15:43:00.001+02:002009-02-07T23:08:27.102+02:00GORM executeQuery problemAs far as You know <a href="http://grails.org/doc/1.0.x/ref/Domain%20Classes/executeQuery.html">executeQuery</a> method allows the execution of <a href="http://grails.org/doc/1.0.x/guide/single.html#5.4.3%20Hibernate%20Query%20Language%20%28HQL%29" class="guide">HQL queries</a> against a domain class. I never tried it before cause used dynamic finders instead. But when I first tried to execute simple HQL query:<br /><blockquote><strong><span style="font-family:courier new,courier;">DocumentRevision.executeQuery("select max(dr.versionNumber) from DocumentRevision dr")</span></strong></blockquote>I've got an exception:<br /><blockquote><strong><span style="font-family:courier new,courier;">Caused by: org.hibernate.hql.ast.<span class="highlight">QuerySyntaxException: DocumentRevision <span>is not mapped.</span></span></span></strong></blockquote>That was quiet surprised for me cause <span><span style="font-weight: bold;">DocumentRevision</span> domain class is mapped and I could perform all CRUD operations with it.<br /><br />Reason for that exception was </span><span>there is one somewhat frustrating difference between <a href="http://grails.org/GORM">GORM</a> and <a href="http://www.hibernate.org/">Hibernate</a> default behaviors. By default in <a href="http://www.hibernate.org/">Hibernate</a> the short class name is used and as long as the domain short class name is unique then this is fine. So in my case I should include <span style="font-weight: bold;">DocumentRevision</span> with whole package name:<br /><blockquote><strong><span style="font-family:courier new,courier;">DocumentRevision.executeQuery("select max(dr.versionNumber) from com.myorg.myproject.core.domain.DocumentRevision dr")</span></strong></blockquote>But <span>the easiest way I discovered of to work around this is to use a couple of <a href="http://groovy.codehaus.org/">Groovy</a> shortcuts:<br /><blockquote><strong><span style="font-family:courier new,courier;">DocumentRevision.executeQuery("select max(dr.versionNumber) from ${DocumentRevision.name} dr")</span></strong></blockquote>"<span style="font-weight: bold;">$DocumentRevision.name</span>" is the equivalent of "<span style="font-weight: bold;">DocumentRevision.class.getName()</span>". It's not much longer than what I originally tried, so I stopped research on mentioned solution.<br /></span></span>Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com4tag:blogger.com,1999:blog-6599286836593454641.post-59877798003259826392009-02-07T15:26:00.000+02:002009-02-07T16:01:03.512+02:00Grails clean commandMany times I faced the situation when <a href="http://www.grails.org/">Grails </a>application has been screwed and comes up with mysterious error messages. Particularly <a href="http://www.grails.org/">Grails</a> can create columns in database for the fields that were removed from the domain entity long time ago, services perform logic that also was removed long tome ago, etc. In that case try to execute command:<br /><blockquote><strong><span style="font-family:courier new,courier;">grails clean</span></strong></blockquote>If its still not working properly after that the last option is to clean <a href="http://www.jetbrains.com/idea/">IntelliJ IDEA</a> cache.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-13532571919672559022009-02-07T15:00:00.004+02:002009-02-07T23:11:48.479+02:00Unit testing: testing service in 3 different ways (part I)Let's start with simple unit testing. If someone will be interested I could improve it with more complicated features. In part I we will use <a href="http://groovy.codehaus.org/ExpandoMetaClass">ExpandoMetaClass</a> approach for unit testing.<br /><br />For instance, we have simple <span style="font-weight: bold;">Document</span> domain class:<blockquote><br /><pre>class Document {<br /> String name<br /> String description<br /> Date creationTime<br /> Date lastModifiedTime<br /> Long revisionCount<br /> User owner<br /><br /> static constraints = {<br /> name(blank: false, maxSize: 64)<br /> description(nullable: true, maxSize: 1024)<br /> }<br /><br /> static belongsTo = [User]<br /><br /> String toString() {<br /> """Document [name: ${name}, <br /> description: ${description}, <br /> lastModifiedTime: ${lastModifiedTime}]"""<br /> }<br /><br />}<br /></pre></blockquote>And let's create a simple <span style="font-weight: bold;">Document service</span> for handing save and retrieve operations:<br /><blockquote><pre>class DocumentService {<br /><br /> def saveDocument(Document document) <br /> throws InvalidDocumentException {<br /> if (document.validate()) {<br /> document.save() <br /> } else {<br /> throw new InvalidDocumentException(<br /> document: document) <br /> }<br /> }<br /><br /> def retrieveDocumentByIdAndOwner(Long id, User owner) <br /> throws DocumentNotFoundException {<br /> Document document = Document.findByIdAndOwner(id, owner)<br /> if (!document) {<br /> throw new DocumentNotFoundException([id: id, <br /> owner: owner].toMapString())<br /> }<br /><br /> document<br /> }<br /><br />}</pre></blockquote>Lets create simple unit test for listed service using <a href="http://groovy.codehaus.org/ExpandoMetaClass">ExpandoMetaClass</a> approach. As far as You remember during unit tests <a href="http://www.grails.org">Grails</a> <strong class="bold">does not</strong> inject any of the dynamic methods present during integration tests and at runtime. So we have to mock them in our tests.<br /><blockquote><pre>class DocumentServiceTests extends GroovyTestCase {<br /><br /> def documentService<br /><br /> void setUp() {<br /> <span style="color: rgb(153, 0, 0);"> <br /> // We have to initialize service class,<br /> // there is no dependency injection.</span><br /> documentService = new DocumentService()<br /> }<br /><br /> void testSaveDocumentSuccess() {<br /> def documentToSave = new Document(<br /> name: "Document name", <br /> description: "Document description", <br /> lastModifiedTime: new Date(), <br /> creationTime: new Date(), <br /> revisionCount: 1L, <br /> owner: new User())<br /><br /> <span style="color: rgb(153, 0, 0);"> <br /> // Dynamically add (mock) method validate to all <br /> // instances of Document class and <br /> // suppose it always return true. </span><br /> Document.metaClass.static.validate = {<br /> return true<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);"> <br /> // Dynamically add (mock) method save to all <br /> // instances of Document class and <br /> // suppose it always return true. </span><br /> Document.metaClass.static.save = {<br /> return true<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Saving will pass cause validate and <br /> // save methods will return true.</span><br /> documentService.saveDocument(documentToSave)<br /> }<br /> <br /> void testSaveDocumentFailure() {<br /> def documentToSave = new Document(<br /> name: "Document name", <br /> description: "Document description", <br /> lastModifiedTime: new Date(), <br /> creationTime: new Date(), <br /> revisionCount: 1L)<br /><br /> <span style="color: rgb(153, 0, 0);"> <br /> // Dynamically add (mock) method validate to all <br /> // instances of Document class and <br /> // suppose it always return false. </span><br /> Document.metaClass.static.validate = {<br /> return false<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Saving will fail cause validation will fail.</span><br /> shouldFail(InvalidDocumentException) {<br /> documentService.saveDocument(documentToSave)<br /> }<br /> }<br /><br /> void testRetrieveDocumentByIdAndOwnerSuccess() {<br /> <span style="color: rgb(153, 0, 0);"> <br /> // Mock dynamic finder method to all <br /> // instances of Document class and <br /> // suppose it always return some document. </span><br /> Document.metaClass.static.findByIdAndOwner = { <br /> Long id, User owner -><br /> return new Document(id: id, <br /> name: "Document name", <br /> description: "Document description", <br /> lastModifiedTime: new Date(),<br /> creationTime: new Date(), <br /> revisionCount: 1L, <br /> owner: owner)<br /> }<br /> <span style="color: rgb(153, 0, 0);"> <br /> // Test the target method, <br /> // it will return supposed document. </span><br /> def foundDocument = documentService.retrieveDocumentByIdAndOwner(<br /> 1L, new User())<br /><br /> assertNotNull foundDocument<br /> assert "Document name" == foundDocument.name<br /> assert "Document description" == foundDocument.description<br /> assert 1 == foundDocument.revisionCount<br /> }<br /><br /> void testRetrieveDocumentByIdAndOwnerFailure() {<br /> <span style="color: rgb(153, 0, 0);"> <br /> // Mock dynamic finder method to <br /> // all instances of Document class and <br /> // suppose it always return NULL. </span><br /> Document.metaClass.static.findByIdAndOwner = { <br /> Long id, User owner -><br /> return null<br /> }<br /><br /> <span style="color: rgb(153, 0, 0);"><br /> // Test the target method, it will fail cause <br /> // no document instance will be found. </span><br /> shouldFail(DocumentNotFoundException) {<br /> documentService.retrieveDocumentByIdAndOwner(<br /> 1L, new User())<br /> }<br /> }<br /><br />}</pre></blockquote>As You can see using <a href="http://groovy.codehaus.org/ExpandoMetaClass">ExpandoMetaClass</a> is quiet easy. But be aware of using such approach cause some nuances are present:<br /><ol><li>Not all dynamic methods can be mocked using <span style="font-weight: bold;">metaClass</span> property.</li><li>Mocks using <a href="http://groovy.codehaus.org/ExpandoMetaClass">ExpandoMetaClass</a> are created for whole tests (including integration tests). So if You mock some method for particular class in some unit test it will affect execution of mentioned method for particular class in <span style="font-weight: bold;">other</span> tests, so result can be unpredictable.<span style="font-weight: bold;"><br /></span></li></ol>Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-58840853049176865152009-02-07T14:41:00.000+02:002009-02-07T16:03:38.830+02:00Testing in Grails: common information<a href="http://grails.org/">Grails</a> supports the concepts of:<br /><ol><li>Unit testing - testing individual methods or blocks of code without considering for surrounding infrastructure. You have to mock these methods or blocks using something like <a href="http://docs.codehaus.org/display/GROOVY/Groovy+Mocks" target="blank">Groovy Mock</a> or <a href="http://groovy.codehaus.org/ExpandoMetaClass" target="blank">ExpandoMetaClass</a>. Alternatively, you could using the <a href="http://www.grails.org/Testing+Plugin" target="blank">Testing plugin</a>. I will show all 3 approaches in future posts.<br /></li><li>Integration testing - you have full access to the <a href="http://grails.org/">Grails </a>environment within the test. <a href="http://grails.org/">Grails</a> will use a database (HSQLDB, MySQL or another found in <a href="http://grails.org/">Grails </a>configuration) for integration tests and clear out all the data from the database in between each test.</li><li>Functional testing - involve testing the actual running application. <a href="http://grails.org/">Grails </a>has support for functional testing via <a href="http://webtest.canoo.com/" target="blank">Canoo WebTest</a> plug-in.</li></ol>Also be aware that You have to test all layers of the application:<br /><ol><li>Domain entities - usually You have to write unit tests for validation process.</li><li>Services - usually You have to write unit and integration tests to be sure that services are working properly.</li><li>Controllers - usually You have to write unit and integration tests to be sure that controllers are working properly.</li></ol>We will cover all mentioned tests on real examples for all layers in future posts.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0tag:blogger.com,1999:blog-6599286836593454641.post-64082736472074503332009-02-07T14:09:00.000+02:002009-02-07T16:02:38.669+02:00Useful books and resources concerning Groovy/GrailsWhen I just started with <a href="http://groovy.codehaus.org/">Groovy</a>/<a href="http://grails.org/">Grails</a> I faced the problem of finding good books/blogs/resources. Therefore I want to share some useful links for the beginners:<br /><ol><li>I recommend <a href="http://apress.com/">Appress books</a> concerning Groovy/Grails especially <a href="http://apress.com/book/view/1430210451">Beginning Groovy</a>.</li><li><a href="http://grails.org/doc/1.0.x/">Grails reference</a> is quiet laconic but useful in any time.</li><li>If You have any problems or need qualified support I recommend <a href="http://www.nabble.com/">Nabble forums</a>, there are a lot of posts concerning <a href="http://groovy.codehaus.org/">Groovy</a>/<a href="http://grails.org/">Grails</a> problems.</li><li>Blogs on <a href="http://www.blospot.com/">www.blospot.com </a></li></ol>This post will be updated frequently cause I will try to ind more useful resources.Taras Matyashovskyhttp://www.blogger.com/profile/15219016865122313846noreply@blogger.com0