October 25, 2012

2k Unit Tests in One Year – Lessons Learned

by Stefan

I was in the lucky position to work on a green field project during the last two years. At the time the project started someone pointed me to the clean code books by Robert C. Martin. The proposed approach to professional software development seemed to be refreshingly different to the approach I was used to before. So the direction was clear: most of the code that has been created during the last two years was written test driven. I found myself writing an amount of tests in a way I never did before. I actually wrote something between 1k and 2k tests in the first year which is more than 5 tests per day. Today, the whole test suite is more than twice the size and provides a code coverage of more than 90 percent. (footnote: the UI code is actually split using an MVC like approach. The view code is not tested at all, as it doesn’t make sense IMHO to test the composition and labeling of widgets with unit tests.)

The Debugger was my best friend

When I started developing software in my first job, the debugger was my best friend. I used it to understand existing code, and even more important, to verify that my logics work. I was really proud that I was able to watch and inspect several variables simultaneously. Debugging code was one of the great insights I gained and I considered it to be the key to mastering software complexity.
Continue reading

Advertisements
June 27, 2012

Eclipse JUnit Editor Templates

by Stefan

I recently had to set up a new Eclipse (STS) workspace and one of the first things I do is configuring some templates for JUnit Tests. Most of the tests have a skelleton like this:

import org.junit.Before;
import org.junit.Test;

public class SocialNetworkGeneratorTest {
  private SocialNetworkGenerator generator;

  @Before
  public void setUp() {
    generator = new SocialNetworkGenerator();
  }

  @Test
  public void testSth() {
    // do sth with "generator" field
  }
}

The following Eclipse Editor Template creates the setup method and stores an instance of the class under test in a field. It also handles all necessary imports.

${:import(org.junit.Before)}

  private ${type} ${name};

  @Before
  public void setUp() {
    ${name} = new ${type}();
    ${cursor}
  }

Simply assign a catchy name for the template like setup and I’m sure you will have even more fun when writing JUnit Tests.

Adding a Java Editor Template in Eclipse

For the sake of completeness the template for test cleanup:

${:import(org.junit.After)}
  @After
  public void tearDown() {
    ${cursor}
  }

December 2, 2011

Intercepting RequestFactory requests

by Stefan

With RequestContext#fire() it is possible to provide a Receiver instance (“Callback”) to handle the result of a request to the server. One could think of some use cases where the same processing should be done for all RequestFactory calls, e.g.

  • Indicate a running request, e.g. change the mouse cursor, display a status or similar.
  • Handle http error codes, e.g. session time-outs or server unavailability.
  • Handle request time-outs.

To intercept all requests made via a RequestFactory it is possible to provide a customized RequestTransport implementation. This is done during the initialization:

import com.google.gwt.core.client.GWT;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.SimpleEventBus;
import com.google.web.bindery.requestfactory.shared.RequestTransport;

import cleancodematters.requestfactory.tutorial.client.PizzaRequestFactory;

public class CustomTransportDemo {

  public PizzaRequestFactory initializeRequestFactory() {
    
    EventBus eventBus = new SimpleEventBus();
    RequestTransport transport = new CustomRequestTransport();
    
    PizzaRequestFactory factory = GWT.create( PizzaRequestFactory.class );
    factory.initialize( eventBus, transport );
    return factory;
  }
}

CustomRequestTransport extends the DefaultRequestTransport implementation and can do the pre- and post processing for all requests. See this very basic example to change the cursor during a running request:

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style.Cursor;
import com.google.web.bindery.requestfactory.gwt.client.DefaultRequestTransport;
import com.google.web.bindery.requestfactory.shared.ServerFailure;

public class CustomRequestTransport extends DefaultRequestTransport {

  @Override
  public void send( String payload, TransportReceiver receiver ) {
    doBeforeSend();
    super.send( payload, wrap( receiver ) );
  }
  
  private TransportReceiver wrap( final TransportReceiver delegate ) {
    return new TransportReceiver() {
      
      public void onTransportSuccess( String payload ) {
        doOnSuccess();
        delegate.onTransportSuccess( payload );
      }
      
      public void onTransportFailure( ServerFailure failure ) {
        doOnFailure( failure );
        delegate.onTransportFailure( failure );
      }
    };
  }

  protected void doBeforeSend() {
    // Some processing before the request is send
    Document.get().getBody().getStyle().setCursor( Cursor.WAIT );
  }

  protected void doOnSuccess() {
    // Some processing on success
    Document.get().getBody().getStyle().setCursor( Cursor.DEFAULT );
  }
  
  protected void doOnFailure( ServerFailure failure ) {
    // Some processing on failure
    Document.get().getBody().getStyle().setCursor( Cursor.DEFAULT );
  }
}
October 1, 2011

Polymorphic entities with GWT 2.4

by Stefan

GWT 2.4 finally adds polymorphism support to the RequestFactory infrastructure (detailed description). Here’s a small example on how to use it.

The scenario is well known from your first OO lesson. A basic class Vehicle is extended by the sub classes Car and Truck. Our back-end service layer allows clients to load a list of vehicles:

public class VehicleProvider {
  public List<Vehicle> getListOfVehicles() {
    return Arrays.asList( new Vehicle(), new Car(), new Truck() );
  }
}

To enable to RequestFactory logic to “know” all subclasses for Vehicle, use the new @ExtraType annotation to reference all known sub-types:

import java.util.List;

import cleancodematters.requestfactory.polymorphism.server.VehicleProvider;

import com.google.web.bindery.requestfactory.shared.ExtraTypes;
import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.Service;

@Service(value=VehicleProvider.class)
// Reference CarProxy and TruckProxy which extend VehicleProxy
@ExtraTypes( {CarProxy.class, TruckProxy.class} )
public interface VehicleRequestContext extends RequestContext {
  Request<List<VehicleProxy>> getListOfVehicles();
}

That’s it. You can find the full example on github.

June 29, 2011

Eclipse: Running all JUnit tests at once

by Stefan

When developing test driven it is essential to be able to run all existing unit tests over and over again as fast as possible. When the application gets larger the natural way to modularize is to distribute the code among multiple projects. I am not aware of tooling that ships with Eclipse and that allows you to run all JUnit tests based on a multi-project selection or on a selected working set.

I’ve used several workarounds in the past (Ant script, TestSuites, Maven build), but none was really satisfying. I recently stumbled upon the ClassPathSuite by Johannes Link which offers exactly what I was looking for. The library internally scans the classpath for classes with JUnit4 annotated methods and then executes all found tests. Sounds simple. This classpath-based solution also has the advantage that any Eclipse classpath container can be used so this works with OSGi-based bundles as well as with Maven projects, for instance.

Setup a ClassPathSuite test project

All you need to do is to create a new project and add a single class:

import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.runner.RunWith;

@RunWith(ClasspathSuite.class)
public class RunAllTests {
}

If you’re with Maven, the library can be referenced like this (if not follow this link):

 <repositories>
    <repository>
      <id>http://maven.xwiki.org</id>
      <url>http://maven.xwiki.org/externals</url>
    </repository>
  </repositories>
  
  <dependencies>
    <dependency>
      <groupId>cpsuite</groupId>
      <artifactId>cpsuite</artifactId>
      <version>1.2.5</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

Continue reading

June 22, 2011

Running integration tests against a GWT RequestFactory based back-end

by Stefan

Update 20.07.2011: Added post.releaseConnection() class to HttpPostTransport

If your app uses GWT’s RequestFactory capabilities, a well-defined external interface to your back-end is automatically exposed. The definition is provided using the RequestContext interfaces that are mapped to a service running in the back-end. Example:

Back-end service:

package cleancodematters.server;

import cleancodematters.server.domain.Pizza;

public interface PizzaDao {
  void save( Pizza pizza );
  Pizza findById( Long id );
}

RequestFactory with RequestContext (see the first tutorial for the full code):

package cleancodematters.client;

import cleancodematters.server.DaoLocator;
import cleancodematters.server.PizzaDao;

import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.RequestFactory;
import com.google.web.bindery.requestfactory.shared.Service;

public interface PizzaRequestFactory extends RequestFactory {

  @Service(value = PizzaDao.class, locator = DaoLocator.class)
  public interface PizzaRequestContext extends RequestContext {
    Request findById( Long id );
    Request save( PizzaProxy pizza );
  }

  PizzaRequestContext context();
}

With this infrastructure, not only the JS-based client running in the browser but, in fact, any Java client can communicate with your back-end. Although this might not be the full fledged interface for integration with other systems, it is perfectly suitable for running any kind of headless tests against your back-end. This can be functional tests as well as load and performance tests.

All we need to do is to replace the default XHR-based transport layer with a pure JRE compatible implementation. In this example, we use the Apache HttpClient lib. Similar to the tutorial on unit testing a helper class provides a factory method to create RequestFactory instances:

Continue reading

June 18, 2011

Tutorial GWT Request Factory – Part II

by Stefan

In the first part of the tutorial we set up EntityProxy classes for our back-end entities pizza and ingredient. A PizzaRequestContext was introduced that represents the client-side facade for the PizzaDao in the back-end.

Now, a natural next step is to write some kind of controller logic that uses the PizzaRequestContext to communicate with the back-end. Let’s call this controller PizzaManager:

package cleancodematters.client;

import com.google.web.bindery.requestfactory.shared.Receiver;

public class PizzaManager {

  private final PizzaRequestFactory factory;

  public PizzaManager( PizzaRequestFactory factory ) {
    this.factory = factory;
  }

  public void findById( Long id, Receiver<PizzaProxy> receiver ) {
    factory.context().findById( id ).with( "ingredients" ).fire( receiver );
  }
}

The manager gets a RequestFactory instance passed into the constructor. This is a good idea as creating the RequestFactory requires a GWT#create() call which doesn’t work in plain JUnit tests. See my previous post on how to use GIN get the instance injected automatically.

How can we test the implementation of findById() with plain JUnit tests? One approach is to use a mocked PizzaRequestFactory instance. In our test we then have to ensure that the method chain factory.context().findById( id ).with( "ingredients" ).fire( receiver ) is called correctly. This test code is hard to write and also tied very closely with implementation details. In general, fluent interfaces are nice to read (but often violate the Law of Demeter, btw) but testing this code with mocks can be really cumbersome.

A better approach in my view is to use GWT’s RequestFactory infrastructure and replace the transport layer with some “in memory” processing that is independent of the browser infrastructure. Fortunately, GWT already provides a class for this: InProcessRequestTransport. This approach has another advantage: We also test the error-prone reference of nested entities (with( "ingredients" ) in the example).
Continue reading

June 4, 2011

Tutorial GWT Request Factory – Part I

by Stefan

Update 30.12.2012: All examples are reviewed and updated to GWT 2.5. Enjoy!
Update 24.09.2011:
I finally managed to push the complete tutorial project to github. It is based on GWT 2.4. 2.5. Looking forward to your feedback.

The first part of this tutorial describes how to set up a Request Factory (RF) based client-server communication in GWT. In contrast to the example at GWT home, a classic DAO pattern is used at the server-side with a clear separation between entity (passive, stateful) and dao/service (active, stateless). As this is not the default way, some additional helper classes (“locators”) need to be implemented. However, I think the benefit of a cleaner architecture is worth the price of some additional lines of code.

The second part will deal with testing RF-based classes in the GWT client.

Prerequisites

You should have the GWT SDK installed and a GWT compatible project in the IDE of your choice available. To make the example run you need some additional libraries on the classpath:

  • org.json.*
  • a JSR 303 Bean Validation implementation, e.g. hibernate-validator

When using Maven, simply add these dependencies:

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20090211</version>
</dependency>

<!-- Validation API -->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.0.0.GA</version>
</dependency>

<!-- Validation Implementation -->
<dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-validator</artifactId>
 <version>4.3.0.Final</version>
</dependency>

<!-- Need some logging provider for SLF4J -->
<dependency>
 <groupId>ch.qos.logback</groupId>
 <artifactId>logback-classic</artifactId>
 <version>0.9.30</version>
</dependency>

Without Maven you can use gwt-servlet-deps.jar from the GWT SDK (containing the JSON packages) and download the hibernate-validator jar with its dependencies.
Continue reading

May 29, 2011

Improved ExceptionHandling with GWT RequestFactory

by Stefan

Server Side Exceptions

The default setting for handling exceptions in the server is not optimal. An exception on the server-side is caught and handled by the class DefaultExceptionHandler. Only the exception message is transferred to the client but nothing is logged. As this happens inside an http 200 response, the web app container doesn’t notice that something went wrong. The default behavior can be changed by replacing the DefaultExceptionHandler during the initialization of the RequestFactory servlet.

Therefore, a custom servlet that extends from the default RequestFactoryServlet needs to be defined to pass a custom exception handler in the constructor.

package cleancodematters.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.web.bindery.requestfactory.server.ExceptionHandler;
import com.google.web.bindery.requestfactory.server.RequestFactoryServlet;
import com.google.web.bindery.requestfactory.shared.ServerFailure;

public class CustomRequestFactoryServlet extends RequestFactoryServlet {

  static class LoquaciousExceptionHandler implements ExceptionHandler {
    private static final Logger LOG = LoggerFactory.getLogger( LoquaciousExceptionHandler.class );

    @Override
    public ServerFailure createServerFailure( Throwable throwable ) {
      LOG.error( "Server error", throwable );
      return new ServerFailure( throwable.getMessage(), throwable.getClass().getName(), null, true );
    }
  }

  public CustomRequestFactoryServlet() {
    super( new LoquaciousExceptionHandler() );
  }
}

Continue reading

May 19, 2011

GWT RequestFactory with GIN

by Stefan

Creating GWT RequestFactory instances requires a GWT.create() call. These calls should be outside of your classes under test, as GWT.create() internally invokes native JavaScript code. This causes a ExceptionInInitializerError when run as a plain JUnit test.

A very elegant solution is to use Dependency Injection with GIN and let the framework create and assemble both the RequestFactory and corresponding RequestContext instances. In general, using DI is a good idea for all layers of business application, and GIN brings the well-known concepts of Guice into the GWT world.
Continue reading