Monday, March 10, 2008

Mocking out the logger

I have a simple CachingService that is a wrapper for Ehcache.   I wanted to create a unit test out of CachingService, since it doesn't have any dependencies.  However after running the test I was getting an error:  "groovy.lang.MissingPropertyException:  No such property: log for class:  CacheService".

Oops I forgot I have some logging inside my CachingService class.   At runtime Grails auto-magically injects a "log" property into service classes.  If my test was an integration test then there wouldn't be a problem.   So I have two options, either mock out the logger or run my test as an integration tests.   I decided to mock out the logger, which required me to do the following:

1.  Create a MockLogger class (primarily since I will probably have to mock out the logger in other classes in the future)

class MockLogger {
  void info(message) {}
  void warn(message) {}
  void debug(message) {}
  void error(message) {}
}

2.  Inject my MockLogger as a property named "log" via getLog() into my service class via ExpandoMetaClass

void setUp() {
  CachingService.metaClass.getLog = { -> new MockLogger() }
}

3.  Reset the state of CachingService before dynamically adding the property "log"

void tearDown() {
  def remove = GroovySystem.metaClassRegistry.&removeMetaClass
  remove CachingService
}

There may be other ways to mock out the logger, but this approach seemed simple enough.  Do you have an easier approach?  If so please drop a comment.





Sunday, March 9, 2008

Testing Approach

To be honest I'd don't do as much as testing as I should.  I really understand the value of testing my code and love to see the green bar.  However anytime in the past I needed to write a test that required mocking I always cringed.   Although EasyMock and JMock are great tools they can be a pain sometimes for that code with heavy dependencies.

Groovy has some great support for testing, including:
  • GroovyTestCase (which extends on JUnit)
  • Testing for exceptions via "shouldFail()"
  • First-class mocking support built-into the language
In Grails when you create a controller, domain, job, or service it will automatically create a test class for it.  However it creates them all as integration tests which run slower than unit tests because the entire Grails environment needs to get bootstrapped to success run the tests.   I can understand testing the domain classes as integration tests because they need to hit the database.  

Most of the code that I'm going to write should be in the service layer.  So I need the service layer tests to run quickly so I can get a quick feedback.  Lucky Groovy makes it pretty easy for me to mock out the domain layer in my service tests.   Below is an example of a service layer test that mocks out the "Site" domain object:


void testAccessDataObject() {
  def service = new SampleService()
  def siteMock = new groovy.mock.interceptor.StubFor(Site)
  siteMock.demand.get {id ->
    return new Site()
  }

  siteMock.demand.getName {id ->
    return 'my sample site'
  }

  def results
  siteMock.use {
    results = service.accessDataObject()
    assertEquals 'my sample site', results.name
  }
}

Currently I am on the fence on whether controllers should be written as unit or integration tests.  I am leaning towards integration tests because I will be able to write a test that tests the entire mvc stack.   What are your thoughts on testing the controller?

Just a little tip for running test with grails.  Normally you run the "grails test-app" command to run both the unit and integration tests.  If you just want to run the unit tests you can run "grails test-app -unit" and just the integration tests with "grails test-app -integration".

There's a Grails plugin to integrate Canoo Webtest to able to write functional tests (aka user acceptance tests).  You can write your functional tests in Groovy instead of xml if you desire.  I haven't tried it yet, but there's also a plugin for integrating Cobertura test coverage tool.  

Because of Groovy and Grails excellent testing support I would be a fool to write Siteproducer without testing.  I can't guarantee 100% test coverage, but at least 60% would be great.



Friday, March 7, 2008

Development Tool

Intellij is my integrated development environment tool of choice!  However some may not agree with me, but its the tool I have chosen.   One issue that some have with Intellij is the cost.  Intellij is not an open source development environment, so you have to pay to play.   However in my humble opinion the cost of Intellij easily gives you a return on your investment with its productivity gains.

To date Intellij has the best Groovy and Grails support.   Eclipse via a plugin has some Groovy support, but no Grails support.   Netbeans has some Groovy and Grails support.  
One problem that you have with a dynamic language is tools support.   Since there is no "typing" its very difficult (if not near impossible) to support code completion and refactoring.  Luckily the crafty developers of Intellij have done a pretty good job in supporting code completion and some refactoring (but not as good as their Java refactoring).
Intellij has options to create all the standard Groovy and Grails artifacts.  Including but not limited to:  Groovy classes, Groovy scripts, Groovy test cases, domain models, controllers, services.  

The coolest feature of the Grails support is the domain model dependency diagram.   You can see a graphical representation on how your domain objects relate.   This diagram is very similar to an entity relationship diagram.  The diagram isn't a static picture, you can create new relationships by dragging lines between the domain objects.   Intellij then will include the appropiate code in your domain objects to make the relationships happen.  Below is an example of a dependency diagram:
























If you are going to be alot of development with Groovy and Grails I would highly recommend you take a look at Intellij.


Siteproducer

The application I have decided to write with the Grails framework is Siteproducer, my take on an easy to use content management system.  Every good application needs a logo, so here is the logo for Siteproducer:





You may be scratching your head and thinking "why another content management system?"  Well in my humble opinion most open source content management systems are clunky and/or have a horrible user experience (ux).   

Siteproducer will be developed with the Grails framework for back-end and use Ext JS for the user interface.

Introductions

Welcome to "Groovy and Grails:  The Blog".   This is a specialized blog that will focus on  my adventures of creating an application with the Groovy language and the Grails framework.

I jumped onto the Ruby on Rails train along time ago.  I was amazed at the productivity gains that Ruby on Rails gives you.  Plus I loved the expressiveness of the Ruby language.  However like most developers coming from the Java world I ran into some brick walls with Ruby on Rails.   One big issue was losing all the 3rd party libraries that I had come to rely on (i.e. full-text searching, pdf generators,image generators,  development tools integration, etc.).   Yeah Ruby on Rails had a great productivity with development, but the same couldn't be said for deployment.  You also most needed to be a rocket scientist or a super linux admin to deploy a Rails application for ultimate performance.

Then Groovy and Grails came to be:   I get an expressive language in the form of Groovy and a web framework that supports the "convention over configuration" paradigm.  Plus I can use all my 3rd party libraries that I am use to and deploy applications the same way. 

Just recently I went to the Groovy and Grails Experience in Washington D.C.  For 3 days I received lots of exposure to Groovy and Grails, I learned a heck of alot in such a short time period. 

If you want to learn more about Groovy and/or Grails please visit their respective sites.

I won't be blogging every day, maybe not even every week.   So instead of coming back to this site hoping for updates why don't you go and add this blog to your feed reader?

In my next post I will be talking about the application that I am going to write with the Grails Framework.  I will give you a hint, the name of the application is called "Siteproducer".

If this blog does anything I hope that it will cause you to take look and Groovy and Grails for your future projects.