JUnit 4.7 Verifier Core Rule

Mommy's Little Test Developer

Mommy's Little Test Developer

Continuing with my look at the new core rules in JUnit 4.7 this blog entry will look at the Verifier core rule. This rule is the base class for rules like the ErrorCollector rule which I looked at in a previous post. Using the Verifier core rule it is possible to turn tests which would otherwise pass into failing tests based on a verification state.

There is a single method in the Verifier class that implementors of this rule need to override. The verify method is declared with a throwable exception which should be thrown to indicate verification failure. Here is the method declaration from the Verifier class:

/**
 * Override this to add verification logic.
 * Overrides should throw an exception to indicate that verification failed.
 */
protected void verify() throws Throwable {}

When the Verifier rule is applied the following apply method is used.

public Statement apply(final Statement base, FrameworkMethod method,
  Object target) {
    return new Statement() {
      @Override
      public void evaluate() throws Throwable {
        base.evaluate();
        verify();
      }
   };
}

As can be seen once the base statement evaluation is completed the overriden verify method will be run. This enables the implementation class to fail tests which would otherwise pass.

So how could this be employed in a useful manner? Under what circumstances would it make sense to fail a passing test based on an object state ending up in an incorrect state. John Smart recently wrote an article about Testing Exceptions in JUnit 4.7 in which he implements the verify method in order to check a user is not logged in.

John states that his implementation is probably not the intended use of the Verifier rule, but I don’t think he was far from an intended use. John did provide me with a use case for the Verifier rule though. So my implementation will be used to verify that a user is still in the session once the test has run.

All John failed to implement in his example is a version of the verify method that throws an exception. Following the same pattern as the ErrorCollector rule for my UserInSessionVerifier class that extends Verifier I implemented a verify method that throws a NoUserInSessionException. Below is my UserInSessionVerifier class code:

import javax.servlet.http.HttpSession;
import org.junit.rules.Verifier;

public class UserInSessionVerifier extends Verifier {

  HttpSession session;

  public UserInSessionVerifier(HttpSession session) {
    this.session = session;
  }

  @Override
  protected void verify() throws Throwable {
    NoUserInSessionException.assertNotEmpty(session);
  }
}

As can be seen this is a fairly simple class which extends the Verifier rule class and overrides the verify method. This overriden method throws a NoUserInSessionException if the session user state verification fails, that happens if the session does not contain a user. The session property is initialized in the constructor, which is then passed by parameter to the assertNotEmpty static method of the NoUserInSessionException class. Lets take a look at that class now:

import javax.servlet.http.HttpSession

public class NoUserInSessionException extends Exception {

  private static final long serialVersionUID = 1L;
  private final HttpSession session;

  public NoUserInSessionException(HttpSession session) {
    this.session = session;
  }

  public HttpSession getSession() {
    return this.session;
  }

  public static void assertNotEmpty(HttpSession session) throws Throwable {
    if (session.getAttribute("userName") == null
          || session.getAttribute("userName").equals("")) {
      throw new NoUserInSessionException(session);
    }
  }
}

This standard exception class extends a Throwable subclass, it also  implements the static assertNotEmpty method that contains the user state verification code. In this trivial example if the userName attribute in the session is empty or null a NoUserInSessionException is thrown – as the user state is not what we expected it to be. If the user state is as we expect – that is to say it is populated then this method will not throw an exception and the verify method in UserInSessionVerifier will not cause any tests to fail.

Having looked at our Verifier rule (UserInSessionVerifier) and its associated exception (NoUserInSessionException), lets now look at a test that uses our new UserInSessionVerifier rule.


import static org.junit.Assert.assertTrue;

import javax.servlet.http.HttpSession;

import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.mock.web.MockHttpSession;

public class UserInSessionVerifierExample {

 public HttpSession session = new MockHttpSession();

 @Rule
 public UserInSessionVerifier verifyUserInSession = new UserInSessionVerifier(session);
 @Rule
 public ExpectedException thrown = ExpectedException.none();

 @Test
 public void userInSessionPasses() {
   // Add user to the session.
   session.setAttribute("userName", "testUser");
   assertTrue(true);
 }

 @Test
 public void userNotInSessionFails() {
   // No user added to session
   assertTrue(true);
 }

 // This fails
 // - Because the exception is not returned by base.evaluate() but
 // by the verify() call in the Verifier class apply() method.
 @Test(expected = NoUserInSessionException.class)
 public void userNotInSessionUncaught() {
   // No user added to session
   assertTrue(true);
 }

 @Test
 public void userNotInSessionCaught() {
   // No user added to session
   thrown.expect(NoUserInSessionException.class);
   assertTrue(true);
 }

 @After
 public void removeUserFromSession() {
   if (session.getAttribute("userName") != null) {
         session.removeAttribute("userName");
   }
 }
}

Looking at this class you will notice that there are  2 JUnit 4.7 rules, 4 tests and an @After annotated method in it. Lets look closer at these aspects of the test class now.

The first rule declared is the UserInSessionVerifier rule that we implemented. We pass this rule the MockHttpSession as an argument to the constructor. This rule will be evaluated after each test is run, so if there is no user in the session at the end of a test the rule will fail verification. The second rule used is an ExpectedException rule which will be used to test that when the verification fails we actually recieve a NoUserInSessionException.

The 4 tests all contain a simple passing assertTrue(true) statement which means they should all run successfully. The difference comes in the verification state once the tests complete.  The userInSessionPasses test places a user into the session, thus when the verification rule is applied the state is verified and the test passes successfully. The userNotInSessionFails test does not place a user in the session and although the base statement passes the test fails due to the verification state.

The other 2 tests show how the NoUserInSessionException thrown by the  UserInSessionVerifier method gets handled. The userNotInSessionUncaught method shows that using the expected exception attribute to catch the NoUserInSessionException fails. This fails as the base evaluate method does not throw the exception – which is what the expected exception attribute checks. The exception is thrown by the verfiy method. Using the ExpectedException rule which catches exceptions even during the verification state we can catch this exception. The userNotInSessionCaught test passes as the ExpectedException rules expect method rule is met – the NoUserInSessionException is thrown.

The @After method simply clears the user from the session. As can seen this runs after the verification rule, otherwise the userInSessionPasses test would fail. I included it to test when the verification rule gets fired. I wanted to check that the rule was being fired before any clean up methods.

I belive that John could  update his verifier to check if a user was logged in based on the example presented here. I would be interested to know if he thinks such an implementation would prove to be scalable or not. Shall follow up with him.

Hopefully this has provided you with some ideas on how to use the Verifier rule. Would be great to hear about implementations of it you create and how it gets used. I shall move on to investigate the  TestWatchman rule  in my next installment, so hopefully you will be back for more!

Grails Development IDE Issues

GRRRR!! My IDE keeps crashing....

GRRRR!! My IDE keeps crashing....

After several months of ‘garage’ Groovy and Grails development I have recently spent some time on a commercial Grails based project. This blog aims to share some of the issues I have had with IDE support during this project. I will endeavor to update this entry in the future based on my experiences.

My IDE of choice has been Eclipse for a number of years, but during the project I found reason to switch to NetBeans . The cause for this radical IDE change was the Groovy Eclipse Plugin constantly crashing my Eclipse IDE!

The Groovy Eclipse Plugin does have 2 versions. In defense of the plugin, I switched to using version 2 when working on the project, and updated my Eclipse installation to the Galileo release. This version is an alpha, and I had not had any issues with version 1 in previous versions of Eclipse. The plugin home page does state that both versions are working with Eclipse 3.5. I am certain that I checked this before installing version 2. Although as an alpha release I do concede that some instabilities are to be expected. I had also updated to the 3.5.1 release when the crashes became too much for me!

In attempts to stop the constant IDE crashes I tried several JVM argument updates and even took the more radical step of using a totally different JVM. With each attempt proving futile I decided to browse the Groovy Eclipse Plugin JIRA issues for more specific information. Here I found issues related to the Eclipse installation (GRECLIPSE-409, GRECLIPSE-413) I have and the Groovy Eclipse Plugin version I am using. (GRECLIPSE-417).

GRRRRRRRRRRR!!!!! IDE Support..What IDE Support!

Nope..this one doesn't support it either!

On the recommendation of other team members I installed a version of Netbeans 6.7.1 which came with the Grails plugin installed. There are a quite a lot of things that I don’t like about the Netbeans IDE and the Grails plugin – but at the time of writing this blog entry – at least it is stable, doesn’t crash on me constantly and enables me to actually cut some code. Unfortunatly the Netbeans IDE is slow, the code completion is painfully slow (if it works at all), the Grails plugin hangs in the IDE and the interface is not as familiar to me (as Eclipse).

Thus, for the past week I have found myself using the a command line in a command window to build, run and test the Grails application – much as I did when using Eclipse during the ‘garage’ days. Stuck with an intolerably slow IDE with little to no code completion and frustrated by the whole development process. I am considering moving back to Eclipse and downgrading the Groovy Eclipse Plugin. (Any one got any suggestions/thoughs on that one?)

I throughly enjoy cutting Groovy/Grails code but would like a more productive IDE experience. I realize that a lot of IDE support is in alpha or beta status, but for Grails to gain some traction in the market place and with developers this support needs to exist.

I would love to hear about other peoples experiences with Grails IDE development. Information on plugins that I am unaware of or tips and tricks that would get me back up and running in Eclipse would be appreciated.

UPDATE – 10/01/2009

Almost a week has passed and there have been numerous comments on this blog entry, so I thought I would update it with my current status. I have removed all Eclipse instance from my working machine since the initial writing. These instances have been replaced by the Spring Source Tools (STS) 2.1.0 as recommended in the initial comment on this entry.

I have had several issues with this version – it seems to crash once I install the Subclipse plug-in as per versions of Eclipse 3.5.1. I had to reinstall the STS a few times during the week, but at times it has been stable and quite usable. As it still crashes I don’t consider this to be the end of my quest – so will be reviewing the comments that have been made and acting on them this week. I shall update when I have more information.

Eclipse Tip #1 – Static Import Code Completion

If like me Eclipse is your IDE of choice and you find yourself frustrated by having to add an import statement in order to use common static imports then help is at hand. If you use JUnit 4′s assertThat method, the core Hamcrest matchers or even EasyMock verifiers etc, then this tip will make your life easier.

In order to simplify using these static methods add them to your Eclipse static import favourites. This little gem of functionality is found under Preferences -> Java -> Editor -> Content Assist -> Favorites.

Eclipse Static Import Favouries

Eclipse Static Import Favouries

In the above example I have added the org.junit.Assert.* package to my favourites. Now when I am working on some java code and want to use a static import from this package it will be available in the code completion box, as can be seen below.

Code Completion Static Imports in Eclipse

Code Completion Static Imports in Eclipse

Acknowledgment for this simple tip and a few more must go to Benjamin Winterberg who provided this in his 5 Tips for Customizing Eclipse blog entry. Vote his entry up on DZone by voting here.  Hopefully this tip will make your Eclipse static import use a pleasure and not a frustration from now on.