Thursday, February 28, 2008

A small Gotcha using Groovy's StubFor or MockFor

I (literally) just posted about my first experience with Groovy. I forgot to mention one thing that I got hung up on when using the StubFor class (this applies to MockFor as well).

I have a simple utility method that just reads from a file and returns the text. I wrote the following unit test and it looked like this at first.


1. def void testReadFromFile() {
2. def expectedText = "<test>myXml</test>"
3. def fileStub = new StubFor(File)
4. fileStub.demand.text {
5. return expectedText
6. }
7.
8. fileStub.use {
9. def val = FileIO.readFromFile("x.xml")
10. println("val: " + val)
11. assertEquals("Expected Text not Found", expectedText, val)
12. }
13. }


Do you see anything wrong here? Check out line 4. Still think it looks ok? The problem is that there is no method "text". There is however, a method "getText()". That's right. Even though the code I'm testing looks like this

   new File(fileName).text

and works perfectly fine, under the covers the actually method being called is getText(). Running the unit test from above results in the following error:

   junit.framework.AssertionFailedError: No more calls to 'getText' expected at this point. End of demands.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
at org.codehaus.groovy.runtime.MetaClassHelper.doConstructorInvoke(MetaClassHelper.java:526)
at groovy.lang.MetaClassImpl.doConstructorInvoke(MetaClassImpl.java:2331)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1227)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1157)
...

Line 4 in the unit test above should read like this:


4. fileStub.demand.getText {


So, remember that when using StubFor or MockFor your demands must specify the actual method that will be called.

My First Groovy Experience

For a while now, several people in my office have been diving head first into the Groovy experience (James Lorenzen, Chad Gallemore, Joe Kueser, and Travis Chase). Thanks to these guys, my first Groovy experience went pretty well overall.

I do all of my development in IntelliJ IDEA and with Maven2. So, my first steps were to get the JetGroovy plugin, install Groovy, and get my Maven2 project setup to handle Groovy source. Other than a small hiccup getting the plugin, this all went relatively smoothly.

During this experience, I jumped right in using the StubFor class for some unit testing and XmlSlurper to parse through some XML. Both of these proved extremely easy to use and much better than their alternatives in Java.

So, now to what didn't go well. First, when I'm working on an individual unit or integration test, I just run it in IDEA. When I was writing my first Groovy class (and associated tests), I was having trouble with strange behavior with my unit test. After a short time of extreme confusion, it hit me what was happening. If I didn't make a change to the Groovy class between every test, IDEA would not actually use the class (if that makes any sense). I wasn't seeing any exceptions regarding missing classes, but the code would actually not be run. So, I had to make a change in the unit test class as well as the class under test if I wanted to run the test from IDEA. Fortunately, I confirmed with my coworkers that this problem did not exist in IDEA version 7.0.2 (I was running 7.0). A quick upgrade fixed my problem.

The only other thing I have to complain about is the customization of colors in IDEA for Groovy source. Unlike most, I use a very colorful scheme for development. I happen to be terribly color blind and find it much easier when different things in the code stand out. If you ever get the chance to see my screen, you'll see brown, blue, purple, yellow, red, white, grey, and shades of several of those. So, unfortunately for me, there's not quite as much customization available for Groovy source. Oh well. I'm sure I'll live.

At the end of the day, it was a good experience and gladly I'll continue use Groovy where it makes sense.

Wednesday, February 27, 2008

A couple more Maven2 Plugins

Last week I wrote about using the Maven Build Helper Plugin and just started wandering how many other plugins were out there that could be very useful for me, but that I had not yet discovered. So, after a little searching, I found two other plugins that I really wish I would have known about before this. Note however that I have not tried using them to verify their capabilities.


Maven 2 License Plugin

I really, really could have used in the past. I work on about 5 Open Source projects on Java.Net. Most of those started out being built internally. So right before that initial commit you've got to insert a header in every single file. Additionally, I work on DoD contracts and when we deliver code at the end of each quarter, it must include a Government Purpose Rights header. Yes, that includes replacing the open source headers with the GPR headers.

Anyway, I'll list the features of the plugin so you can decide if you want to go check out the project site here.

  • Check: check if header is missing in some source file
  • Reformat: add headers if missing
  • Custom mappings: enables easy support of new file extensions
  • Variable replacement: You can add some variable in your header, such as ${year}, ${owner} and they will be replaced by the corresponding values taken from the pom or system properties.


JMeter Maven Plugin

I'm not using JMeter on my current project, but I have used it on several previous projects. And, there's nothing better than being able to automate a testing process into your build. That's right, this plugin will run your JMeter tests during your build. Unfortunately, it seems like there may be a lack of documentation. However, I've located one additional resource that even includes report generation in it's example of how to use this plugin.

Check out the plugin's site here.

Enjoy!

Thursday, February 21, 2008

Maven2, Multiple Source Directories, and the Build Helper Plugin

I'm currently working on a project dealing a lot with Web Services. I'm using the CXF Codegen Plugin to generate Java classes from an existing WSDL. However, I need to write a few classes of my own to create a common client interface and a mock implementation in addition to the code generated by CXF.

My dilemma is that Maven2 supports only using a single <sourceDirectory> in the pom. I don't want to use a single source directory because of cluttering my code with the generated source or vice versa. I'd rather not use two separate modules because ... well, I don't want 2 different artifacts exposing virtually the same capabilities.

So, after a few Google searches, I found the Build Helper Maven Plugin.

This plugin allows you to add additional source directories to your module. See my example below. I'm adding the directory of my generated source files, ${basedir}/target/generated/src/main/java (in addition to the default source directory ${basedir}/src/main/java).


<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/target/generated/src/main/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.0.2-incubator</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<!-- This is where the generated source files will be placed -->
<sourceRoot>${basedir}/target/generated/src/main/java</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/wsdl/my.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>

Monday, February 18, 2008

To Dig or Not To Dig

Around the beginning of the year, I thought about writing a post about what I wanted to accomplish this year when it comes to this industry and my career. Basically, a professional New Year's resolution list. I never got around to coming up with an official list; however, there's been one item on my mind quite a bit that is my #1 'resolution'.

It's quite often with my personal- and work-related projects that I have the chance to do something I haven't done before. For example, work with a new open source framework, use a technology for the first time, or play with language I haven't yet touched. There have been some occasions where several weeks/months later I've said to my self, "I should have taken just a little more time to explore that in more detail; dig a little deeper".

My #1 resolution is that whenever I get the opportunity to work on something new, I will take a step back and ask myself, "Is this something I should dig deeper on, or is just touching the surface enough?"

Let me give you an example. I am currently working on an IntelliJ IDEA plug-in during some of my spare time. Part of that process has introduced me to Swing development. I haven't once touched Swing or the java.awt package before this. So, needless to say, I'm learning quite a bit. I get to have fun with things like trying to get components to be certain sizes and figuring out how to enable drag and drop. This is the point I need to stop and ask myself the question, "how far do I want to go?" My point is that I need to figure out, do I simply find answers to my questions so that I can get by creating this plug-in? Or, do I spend some time learning more about many aspects of Swing development; something that will last me much longer than this single engagement.

In this case, I chose (for now) to simply find out the answers to my questions so that I can build the plug-in. I'm doing no other Swing development. Not on other personal projects. Not on any work assignments. Nor do I see myself doing any other Swing development in the near future.

With this resolution, I'm trying to keep those moments of "I should have dug deeper" to an absolute minimum. Maybe for you this is just a common sense example of thinking before you act, but for myself (unfortunately), there have been times I should have done more research to gain a solid understanding vs. just enough to produce what I want. Hopefully at the end of this year I can look back and know that put the right amount of effort into learning new things.

Wednesday, February 6, 2008

Review: Head First Design Patterns

Head First Design Patterns


Topics:
  • Design Principles
  • Design Patterns
  • OOP

Summary:

This books teaches the reader about basic concepts behind several common design principles and patterns. Most chapters begin by creating a scenario that involves a development team being given a task to add functionality to an application. It then walks the reader through implementation options by showing example code in Java, while pointing out pros and cons. This ends up identifying a design principle and showing how a specific design pattern can be applied to the problem at hand. The last couple of chapters transition the reader from working with simple, ideal situations to real world expectations of working with design patterns.


Audience:

Any level developer who has a grasp of OOP and is looking to improve their development skills through design principles and patterns.


Pros:
  • Perfect for an introduction to design patterns and principles (and more advanced literature, e.g. GoF text).
  • Examples do an excellent job of showing the benefits of applied principles and patterns.
  • Plenty of humor to keep the reader interested.
  • Suggestions on where to go after reading this book.

Cons:
  • Goes off-topic to explain details of how RMI works during its discussion of the Proxy pattern, a waste of 10-20 pages.
  • While additional patterns are briefly covered in an appendix, I'd like to see a few of those included in chapters of their own.

Recommendation:


If you've got a grasp on OO concepts, but don't really know much about design patterns, this is the perfect place to start. This book is easy to read and does an excellent job of not just explaining the concepts, but proving them with examples as well.