Archive

Posts Tagged ‘dependency injection’

Playing with JerseyTest (Jersey 2.5.1 and DI)

I’m going to try explaining a trivial REST example. The idea is building a basic schema to start playing with Jersey. When I begin to use some framework, I usually develop a test enviroment for failing fast, and that is what I’m going to do.

The next example has these features:

  • Jersey 2.5.1
  • Dependency Injection
  • JUnit for testing

Classes:

  • Resource: it will attend the HTTP calls.
  • Service: it’s an interface with two implementations, Impl1 and Impl2.
  • ServiceProvider: it will give the apropiate implementation of Service per each request call in runtime.
  • TestBinder: it set the bindings into the Resource.

 


import static org.junit.Assert.assertEquals;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;

import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.process.internal.RequestScoped;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;

public class JerseyInjectionTest extends JerseyTest {

	private static final String EXPECTED_CONTENT = "any string :P";

	/**
	 * Checks that the Resource uses Impl1.class
	 */
	@Test
	public void invokeImpl1(){
		invoke(Impl1.class);
	}
	
	/**
	 * Checks that the Resource uses Impl2.class
	 */
	@Test
	public void invokeImpl2(){
		invoke(Impl2.class);
	}
	
	/**
	 * Checks that Resource.anyContent has always the value of EXPECTED_CONTENT
	 */
	@Test
	public void checkContent(){
		Response response = target("example/content").request().get();
		assertEquals(EXPECTED_CONTENT, response.readEntity(String.class));
	}
	
	private <T extends Service> void invoke(Class<T> service){
		final String serviceName = service.getName();
		Response response = target("example/"+serviceName).request().get();
		assertEquals(service.getName(), response.readEntity(String.class));
	}
	
	/**
	 * Register the Resource and TestBinder in the Application
	 */
	@Override
	protected Application configure() {
		return new ResourceConfig() {
			{
				register(new TestBinder());
				register(Resource.class);
			}
		};
	}

	@Path("/example")
	public static class Resource {

		@Inject
		Service service;
		@Inject
		String anyContent;

		/**
		 * Returns the name of the Service's implementation
		 */
		@GET
		@Path("/{serviceClass}")
		public Response getDynamicInvokedService() {
			return Response.ok(service.getClass().getName()).build();
		}

		/**
		 * Returns always the value of anyContent
		 */
		@GET
		@Path("/content")
		public Response getStaticContent() {
			return Response.ok(anyContent).build();
		}

	}
	
	/**
	 * This class will help Resource to set the @Inject fields.
	 */
	public static class TestBinder extends AbstractBinder{

		@Override
		protected void configure() {
			bindFactory(ServiceProvider.class).to(Service.class);
			bind(EXPECTED_CONTENT).to(String.class);
		}
		
	}

	/**
	 * This class will instance a Services's implementation
	 * per each time that the Resource is called.
	 */
	@RequestScoped
	public static class ServiceProvider implements Factory<Service> {

		private final String serviceName;

		public ServiceProvider(@PathParam("serviceClass") String serviceName) {
			this.serviceName = serviceName;
		}

		@Override
		public void dispose(Service arg0) {}

		@Override
		public Service provide() {
			try {
				return (Service) Class.forName(serviceName).newInstance();
			} catch (Exception e) {
				return null;
			}
		}

	}

	/**
	 * Dummy services
	 */
	public static interface Service {}
	public static class Impl1 implements Service {}
	public static class Impl2 implements Service {}

}

Now we can try new features easily.

I hope that helps.

Advertisements

Mockear métodos estáticos, privados, finales y mas con PowerMock

01/09/2012 3 comments

La inyección de mocks o stubs en tests unitarios es una técnica muy extendida, debido a que  permite eliminar las dependencias externas de las clases a testear, con lo que se simplifica enormemente la creación del entorno de test. Existen varias herramientas, como Mockito, que facilitan enormemente esta tarea al proporcionar métodos sencillos de creación (y verificación) de mocks y stubs. Otra opción que goza de gran aceptación es EasyMock.

Pero, en cuanto a la inyección de dependencias, tanto si se realiza la inyección directamente mediante constructores o setters, o se usan herramientas específicas como, por ejemplo, Guice, en muchas ocasiones aparece el problema de que el diseño apropiado no es el mas adecuado para la inyección de mocks: si para crear un mock de un método estático habría que crear algún tipo de wapper o adaptador, tampoco se pueden usar mocks para métodos privados, a menos que se cambiase la visibilidad a protected y se corriesen los tests contra una clase que, extendiendo de la clase a testear, proporcionase métodos públicos que, de esa manera, permitiesen acceso a los protegidos de la clase base. Pero, en ambos casos, se requiere modificar el código y, además, no se prueba exactamente la clase que se desea.

Estos son algunos de los motivos por los que puede ser útil dedicar algo de tiempo a trastear con PowerMock. Otra razón de peso es que para usar PowerMock no es necesario modificar los tests existentes: PowerMock está diseñado para extender Mockito y EasyMock, en lugar de para reemplazarlos. Como entornos de test soporta JUnit y TestNG. A continuación se muestra una pueba de concepto usando PowerMock para extender Mockito en un entorno de test JUnit4.

Se parte del supuesto de que se desea testear un código que se acaba de escribir y que usa un método estático de otra clase. Si el método no fuese estático, se podría, simplemente, inyectar un mock de la clase de la que se depende sin mas problemas.

La clase con la que se mantiene la dependencia:

public class LegacyCode {
public static String getMessage(){
 return new String("Esto es una castaña (estática)");
 }
public String getAnotherMessage(){
 return new String("Esto es una castaña");
 }
}

La clase que se desea testear:

public class MyClass {
public String methodToTest (){
 return LegacyCode.getMessage();
 }
public String methodToTestNotStatic(LegacyCode legacyCode){
 return legacyCode.getAnotherMessage();
 }
}

Y el test:

public class MyClassTest {
 @Test
 public void testLegacyCode(){
 // Creamos un mock para LegacyCode usando Mockito
 LegacyCode mockLegacyCode = mock(LegacyCode.class);
 // Le indicamos lo que debe devolver en este test en concreto
 when(mockLegacyCode.getAnotherMessage()).thenReturn("Lo que diga el mock");
// Instanciamos y comprobamos el mensaje devuelto
 MyClass myClass = new MyClass();
 System.out.println(myClass.methodToTestNotStatic(mockLegacyCode));
 verify(mockLegacyCode, times(1)).getAnotherMessage();
 }
 }

En realidad, testear no se testea nada, el objetivo es simplemente ver que el mock funciona. Y, en efecto, al ejecutar el test se obtiene la cadena Lo que diga el mock  en lugar de Esto es una castaña.

Nada nuevo hasta aquí para los que ya usan estas técnicas. Pero, ¿ que ocurre al testear el método methodToTest de la clase ? En este caso, al llamar a un método estático, no se puede inyectar un mock tal y como se acaba de ver.

Aquí es donde entra PowerMock. Se puede usar PowerMock para crear el siguiente test, donde en este caso se incluyen los imports para que se pueda apreciar como PowerMock (PowerMockito en este caso) tan sólo extiende, pero no sustituye, a Mockito:

 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.powermock.api.mockito.PowerMockito.mockStatic;
 @RunWith(PowerMockRunner.class)
 @PrepareForTest(LegacyCode.class)
 public class MyClassTest {
 @Test
 public void testLegacyCode(){
 MyClass myClass = new MyClass();
 LegacyCode mockLegacyCode = mock(LegacyCode.class);
 when(mockLegacyCode.getAnotherMessage()).thenReturn("Lo que diga el mock");
 System.out.println(myClass.methodToTestNotStatic(mockLegacyCode));
 verify(mockLegacyCode, times(1)).getAnotherMessage();
 }
 @Test
 public void testMockLegacyCode(){
 mockStatic(LegacyCode.class);
 when(LegacyCode.getMessage()).thenReturn("Esto ya es otra cosa");
 MyClass myClass = new MyClass();
 System.out.println(myClass.methodToTest());
 }
 }

Nota: aunque no aparezca a simple vista en la documentación de PowerMock, es necesario incluir en el classpath javassist.

En este caso se ha creado un mock para la clase completa, aunque tambien podría crearse un mock parcial, sólo para el método estático.

La anotación @RunWith debe añadirse siempre para usar PowerMock. Echando un vistazo puede apreciarse que se ha escogido el PowerMockRunner para JUnit 4.

Para crear mocks de clases con métodos estáticos, debe añadirse además la anotación @PrepareForTest, indicando la clase para la que se creará el mock, en este caso LegacyCode.class. Por lo demás, la única diferencia es que, en lugar de llamar al método mock de Mockito, se llama al mockStatic de PowerMockito.

Ejecutando los tests se obtiene como salida:

Lo que diga el mock
Esto ya es otra cosa

Lo que diga el mock, en lugar de Esto es una castaña, como ya se había visto anteriormente, y Esto ya es otra cosa, en lugar de Esto es una castaña (estática), que es lo que devuelve el método estático.

En resumen, PowerMock añade a Mockito o EasyMock, usados conjuntamente con JUnit o TestNG, la posibilidad de crear mocks para métodos estáticos (clase completa o sólo métodos), métodos privados e incluso constructores. De hecho, la posibilidad de crear mocks para métodos estáticos y constructores roza el terreno de la inyección de dependencias en sí mismo.

 

Inyección de dependencias y de código

Las dos técnicas pueden ser muy útiles para testear o debuggear, o incluso para usar en producción cuando se manejan entornos o configuraciones muy distintas.

Sobre inyección de código: http://www.javacodegeeks.com/2011/09/practical-introduction-into-code.html

Sobre inyección de dependencias: http://code.google.com/p/google-guice/

Por supuesto, hay módulos de Spring para ambos casos.

Android Dependency Injection and Testing Libraries

Before reading, take a look Google Guice, in case you have not heard about yet.

Anything and everything that makes life easier to develop for Android should be looked into. There are a couple of libraries that make testing easier, increase the modularity of your code, and provide already created mock objects:

  1. RoboGuice – This is an adaption of Google’s dependency injection library but for Android
  2. Robolectric -This is a testing framework/platform which works to remove the need for constant mocking of Android objects.  It also works with RoboGuice.

I can’t begin to thank the guy that first introduced me to dependency injection enough. Coming from a C++ world, where objects can’t describe themselves and there is no reflection unless the developer purposefully implements it himself, to a more modern language I often created my own static factories to simulate the @inject pattern. But why reinvent the wheel each and every time if an object can describe itself perfectly to the virtual machine?

If you’ve never seen Dependency Injection (DI) before look at the “simple example” RoboGuice provides on their webpage. At first glance it might seem like a fancy way to clean up the code so that maintainers could focus on just the specifics of the actions within each method. That is a side benefit (a really nice one at that) but only a side benefit. The example does not demonstrate the true power of such a framework in testing and asserting bug-free code.

Without DI in your code base

Let’s take a look at a contrived example of what sort of pain points DI can help conquer and alleviate. Suppose that I have a method which needs some sort of widget that takes user input. How can I test such a method without requiring someone to step through a script (as in written instructions) wherein they manually enter all the different combinations which could result in a real world scenario? That’s expensive and time consuming. I’m not even going to mention the human factor for mistakes (like skipping a test by accident). Oops, I just did (see? So easy to make mistakes!)

If there was a way to instantiate mock constructs without having the parent object’s constructor  grow to 20 arguments long I’d love to jump all over it. Thinking back to design patterns 101, factory objectsprovide a means for decoupling object creation logic from object instantiation. Using a static factory object I could insert a test version whenever I wanted. Take a look:

01 public abstract class WidgetBase implements IWidget{
02 protected ISomeObject mSomeObject;
03
04 public WidgetBase(ISomeObject _obj){
05 mSomeObject = _obj;
06 }
07 }
08
09 public AlertWidgetFactory{
10 static private WidgetBase mTest = null;
11 static private boolean mTestFlag = false;
12 static WidgetBase create(ISomeObject _obj){
13 if(mTestFlag){
14 return mTest;
15 }
16 return new AlertWidget(_obj);
17 }
18
19 static void setTest(WidgetBase _testWidget){
20 mTest = _testWidget;
21 }
22
23 static void setTestFlag(boolean _flag){
24 mTestFlag = _false;
25 }
26 }

Now when I get down to testing my code I can automate everything. During the “setUp” phase of my JUnit unit test I can substitute in some mocked version of “WidgetBase” to return many possible user entries. See how easy to test it makes the following code:

1 public void someMethod(String _value){
2 if(_value == ""){
3 ISomeObject foo = new SomeValueAssigner( _value );
4 IWidget alert = AlertWidgetFactory.create(foo);
5 }
6 //more code...
7 }

Of course, if I have a different class type I want to produce from a factory, I’m going to have to code up a factory just for that object.  (In C++ I’d just template it and have but a single class for a factory. Sometimes templates are a good thing, no? Take that generics!).

With DI in your code

Some might be screaming at me for not using a plain interface instead of an abstract class. There was a point to that. Interfaces can’t describe the constructor and I wanted my object to take parameters in the constructor. But why?

First have a closer look at the code above. Did you notice up above that I’ve got a hard-coded dependency in “SomeValueAssigner?” I’m not truly able to unit test the “someMethod” function as I can’t remove the interdependencies without first creating a factory method for that too! Oh the humanity. How many factory objects are we going to have to create just to test a decently sized code base? Each time I want a new object I’ll potentially have to create for it an interface, abstract base class and/or a factory object. I might also need to add a new method to the factory object for each different constructor it has.

I don’t need to say it but that’s a lot of work. Actually it’s too much work even for the engineers at Google.  This is why they came up with Guice in the first place. DI solves a lot of headaches and saves on needing to reinvent the wheel time after time with some limitations (see InjectionPoints on constructor arguments). It isn’t a replacement for your standard design patterns and doesn’t let you avoid passing arguments into a constructor. RoboGuice is just another tool in your toolset (a very powerful and handy tool).

Avoiding the Emulation Stage

Wouldn’t you know it but testing UI components is hard work. Not only do we need to look at the thing in the first place just to see if all the shapes/sizes/colors are displaying correctly but we also need to make sure it does what it’s supposed to do. Then there’s the waiting period while the emulated Android device warms up. Quoting from Robolectric’s website:

Running tests on an Android emulator or device is slow! Building, deploying, and launching the app often takes a minute or more. That’s no way to do TDD. There must be a better way.

I couldn’t agree more. Waiting on the emulator to compile and load the application for a small, tiny fix is painful.
Robolectric lets you iterate faster.  Iterating quickly leads to better design. Better design leads to less maintenance problems. Less maintenance problems leads to more time to add new features or refine functionality. All these things lead to a better product experience for the end user.
That is tremendously beneficial to your bottom line. Even though this section is very short it’s nearly inversely proportional to the amount of time it will save you.

Conclusions

RoboGuice let’s you test more easily and adds another tool/idiom to help decouple your code. Robolectric let’s you test faster. Put them together and you get an environment where you are working more efficiently and productively. These are two libraries you shouldn’t be without.

 

%d bloggers like this: