keskiviikko 25. helmikuuta 2009

Improving Grails TDD within Eclipse

Grails 1.1 unit testing has support for mocking domain classes/objects. This feature is very nice.

These are additional instructions to the previous ones.

Additional instructions to run a Grails domain class unit test:
1. Copy the below code to a file called [grails app rootdir]/src/java/GrailsAwareGroovyTestSuite.java .
2. Update the Eclipse Run Configuration for the launcher created by the previously posted instructions.
3. Change the Test Class name to "GrailsAwareGroovyTestSuite".
(previous instructions contain the full procedure)

I've posted this to the Grails JIRA, it's GRAILS-4123.

UPDATE: Check the JIRA issue to get the latest version of this code.


import grails.util.BuildSettings;
import grails.util.BuildSettingsHolder;
import groovy.util.GroovyTestSuite;

import java.io.File;

import junit.framework.Test;

import org.codehaus.groovy.grails.compiler.injection.ClassInjector;
import org.codehaus.groovy.grails.compiler.injection.DefaultGrailsDomainClassInjector;
import org.codehaus.groovy.grails.compiler.injection.GrailsAwareClassLoader;
import org.codehaus.groovy.grails.compiler.support.GrailsResourceLoader;
import org.codehaus.groovy.grails.plugins.GrailsPluginUtils;

/**
*
* Adds support for running Grails JUnit Tests from Eclipse JUnit runner or even
* from the command line.
*
* Set GRAILS_HOME environment variable before running the test.
* Change the working directory to the Grails application's root directory.
*
*
* more information: http://quest4grail.blogspot.com/search/label/junit
*
*
* @author Lari Hotari
*
*/
public class GrailsAwareGroovyTestSuite extends GroovyTestSuite {
protected final GrailsAwareClassLoader gcl;

public GrailsAwareGroovyTestSuite() {
File basedirFile = new File(".").getAbsoluteFile();
System.setProperty(BuildSettings.APP_BASE_DIR, basedirFile.getPath());
BuildSettings grailsSettings = new BuildSettings(new File(System.getenv("GRAILS_HOME")), basedirFile);
BuildSettingsHolder.setSettings(grailsSettings);

gcl = new GrailsAwareClassLoader(getClass().getClassLoader());
gcl.setClassInjectors(new ClassInjector[] { new DefaultGrailsDomainClassInjector() });
gcl.setResourceLoader(new GrailsResourceLoader(GrailsPluginUtils.getArtefactResources(".")));
}

public static Test suite() {
GrailsAwareGroovyTestSuite suite = new GrailsAwareGroovyTestSuite();
try {
suite.loadTestSuite();
} catch (Exception e) {
throw new RuntimeException((new StringBuilder()).append("Could not create the test suite: ").append(e)
.toString(), e);
}
return suite;
}

@Override
public Class compile(String fileName) throws Exception {
return gcl.parseClass(new File(fileName));
}
}

Missing the green bar developing Grails apps in Eclipse?


I've been missing the green bar developing Grails apps in Eclipse.
I found a solution to the problem.

Instructions (tested with Grails 1.1-RC1):


Creating Eclipse Run Configuration

1. Open the Run Configurations dialog (Run -> Run Configurations. Switch to Java perspective first. Make sure you've added the GRAILS_HOME classpath variable for a new Grails project.)

2. Browse to the item "Junit" and double click on it. It will create a new Junit run configuration.

3. Select "Run a single test"

4. Enter "groovy.util.GroovyTestSuite" as the Test class

5. Switch to "Arguments" tab.

6. In "VM arguments" field enter "-Dtest=${resource_loc}"

7. Click close


Creating and running a test

1. In the command line: grails create-unit-test GrailsJunit

2. Refresh Eclipse view

3. Open the Junit test

4. Open the Run Configurations dialog (Run -> Run Configurations)

5. Select the Junit run configuration you've created recently.

6. Click "Run"


Changing the behaviour of the Run button's default action

In Eclipse 3.4, the default behaviour of clicking the run button is "contextual".
It's easier to run the test if you can just click the Run button.

1. Open "Window->Preferences"
2. Write "launching" in the filter text box.
3. Select "Always launch the previously launched application" in the "Launch Operation" section.

Now you can execute the test by opening the file and just click the run button. Cool!


Re-run button in the JUnit panel

You won't be able to re-run the test by clicking the button in the JUnit panel.
If you want it to work, you will have to create separate launchers for each test.
Another solution is to edit the launcher's configuration each time you start developing a new class.
This can be done by setting the "VM arguments" property to something like this:
-Dtest=${resource_loc:/GrailsJunitTutorial/test/unit/GrailsJunitTests.groovy}

Quest for the Grail of Programming using Grails

Every programmer seems to seek the Holy Grail of Programming. This tendency can been seen in the numerous attempts to build the best framework ever, the über framework that will solve all of the concerns of application programming.

I'm starting to gather small notes about my quest for the Grail of Programming using the Grails platform.