Strategies for testing static calls in Play projects

Play forum is a place with a lot of healthy doubts. Other day, an interesting topic popped there: How to test static methods. So, let’s talk about a little bit about this subject.

For example, if you have this piece of code:

    public void save(final RecentPhotosURL photosURL,
    		final Function2<String, Integer, Void> callback) {
    	WSRequestHolder holder = WS.url(photosURL.getEndpoint());
    	photosURL.fill(holder);
    	Promise promise = holder.get();
    	promise.map(savePhotosFunction);
    }

How can you test it? You are using WS class and making a static call. Libs like Mockito, only can test instance methods. One way to workaround things here is the usage of a lib which instruments your code and is able to mock some static calls :). This powerful tool is PowerMock. So, to test your method you could use something like this.

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({ WS.class })
    public class NewPhotosSaverTest {

    	@Test
    	public void shouldGetJsonResponseAndSaveIt() {
    		mockStatic(WS.class);
    		Mockito.when(WS.url(url).thenReturn(new MyRequestHolder(url));
    		new NewPhotosSaver(...).save(photosURL,callback)
    	}

    	static class MyRequestHolder extends WSRequestHolder{

    		public MyRequestHolder(String url) {
    			super(url);
    		}

    		public  Promise get(){...}

    	}

    }

Voilà, you can unit test a lot of methods that use static approach. This could be used to test legacy system too :). I have no doubts that use static methods are easier than use a lot of instance methods. The main reason is that you can invoke these methods from everywhere. But oops, this can be your big problem too :(.

Now, if someone has to add some logic in this method, there is a big chance that a new class with some static methods be created. The complexity of this method would be increased because it would be responsible for creating and using objects instead of just use them and, even worst, static calls can be made from every piece of your code. I am not sure if you have seen something like this, but imagine a code inside a template:

    for(photo       code here
    }

So you have to know really well your team before start using static methods everywhere. Another strategy can be used to prevent maintainability problems like this. Instead of using Play API’s directly, you could wrap some of them and force your code to instantiate some objects.

    public class ServiceRequester {
      private String endpoint;

      public ServiceRequester(String enpoint){
        ...
      }

      public Promise get(Map<String,String> params){
        WSRequestHolder holder = WS.url(endpoint);
    		Set<Entry<String, String>> entries = params.entrySet();
    		for (Entry<String, String> entry : entries) {
    			holder.setQueryParameter(entry.getKey(),entry.getValue());
    		}
    		return holder.get();

      }
    }

    //using this code

    public class NewPhotosSaver {
        public void save(final RecentPhotosURL photosURL,
        		final Function2<String, Integer, Void> callback) {
        	ServiceRequester requester = new ServiceRequester(photosURL.getEndpoint());
        	Promise promise = requester.get(photosURL.getParams());
        	promise.map(savePhotosFunction);
        }
    }

Now you can refactor a little more and receive these dependencies as constructor args.

    public class NewPhotosSaver {

        public NewPhotosSaver(ServiceRequester requester){
          ...
        }

        public void save(final RecentPhotosURL photosURL,
        		final Function2<String, Integer, Void> callback) {
        	Promise promise = requester.get(photosURL.getParams());
        	promise.map(savePhotosFunction);
        }
    }

It is easy to test now! Just mock this parameter and test your code without problems.

    @Test
    public void shouldGetJsonResponseAndSaveIt() {
      ServiceRequester requester = mock(ServiceRequester.class);
      when(requester.get(params)).thenReturn(somePromiseHere)
      new NewPhotosSaver(requester).save(photosURL,callback);
      //asserts here
    }

Now you have, at least, two options of approach to your code. You can use this same strategy with your DAO. Instead of create static methods that use JPA.em() or Ebean.something, create instance methods and pass DAO’s instances as arguments to other classes.

Of course you have to think about what kind of approach you prefer, it is possible to mix them too. Your tests send signals about your code, pay attention :). Thanks to Rafael Ponte who talked about this situation with me and inspired me to write this post :).

Advertisements

Take advantage of assets conventions in Play

It is usual when you are working with Play use this kind of code to refer public assets.

   <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/style.css")"/>
   <script src="@routes.Assets.at("javascripts/jquery-1.4.4.min.js")" type="text/javascript">
   <img src="@routes.Assets.at("images/someimage.png"/>

But, Why do you have to write the name of css, javascript and images folder all the time if they are the convention? When you are using a framework is important to take advantage of all things, in order to avoid silly mistakes, like write the wrong name of the folder. For example, at least to me, it would be better if we could write something like this:

   <link rel="stylesheet" href="@Css("bootstrap.min.css")">
   <script type="text/javascript" src="@Js("main.js")"></script>
   <img src="@Image("someimage.png"/>

To achieve this we just have to use the built in controller named Assets. Let’s see the implementation:

  package helpers

  import controllers.routes

  object AssetsHelper {

    object Css {
	  def apply(file:String) = routes.Assets.at("stylesheets/"+file)
    }

    object Js {
	  def apply(file:String) = routes.Assets.at("javascripts/"+file)
    }

    object Image {
	  def apply(file:String) = routes.Assets.at("images/"+file)
    }

}

Now, you just have to import this class to all templates. Change your build.sbt and add this line.

   templatesImport ++= Seq("helpers.AssetsHelper._")

If you want to keep update with a lot of Play tips, follow me here and in my twitter :). Also I have my book available in Leanpub, still only in Portuguese and ASAP in English.

Play, um framework pensado para você e sua empresa

O post de hoje é para fazer você e seu time pensar em que parte da aplicação vocês querem focar no próximo projeto. Para médias e grandes aplicações, o assunto escalabilidade é realmente importante. Os sistemas precisam atender a demanda de novos clientes até o máximo que conseguir mantendo um tempo de resposta dentro do aceitável.

Para exemplificar, instalei duas aplicações que fazem exatamente a mesma coisa em uma instância da Digital Ocean para que vocês tirem as suas conclusões sobre o Play Framework.  Ambas montam uma página baseada numa consulta de banco de dados que retorna 100.000 objetos. É uma aplicação simples, que tem apenas uma classe importante que representa uma Transação Bancária.  Como implementação de pool de conexões, ambas usam o BoneCP, implementação que já vem pronta no Play e por isso usada no exemplo com Servlets. Além disso, as 2 subiram com 1gb de memória.

Aqui estão alguns números obtidos através do uso do Siege para realizer os benchmarks. Vamos olhar os números da aplicação rodando no Tomcat com o NioConnector ativado. Para não ficar nada muito impossível de se imaginar, todos os testes foram realizados simulando 100 usuários acessando a aplicação em lotes de 10. A primeira simulação, para esquentar, foi listando 1000 objetos. Abaixo os números:

  Transactions:		        100 hits
  Availability:		        100.00 %
  Elapsed time:		        6.07 secs
  Response time:		0.51 secs
  Throughput:		        0.35 MB/sec

Fique atento para a linha referente a Availability(Disponibilidade). Agora o teste mais complicado, simulando a listagem de 100000 objetos.

  Transactions:		       54 hits
  Availability:		       54.00 %
  Elapsed time:		       456.44 secs
  Response time:	       28.22 secs
  Throughput:		       0.12 MB/sec

Perceba que a disponibilidade caiu muito!. Vamos agora dar uma olhada nos números obtidos no uso do Play. Abaixo segue os números da primeira simulação com apenas 1000 objetos.

    Transactions:	         100 hits
    Availability:		 100.00 %
    Elapsed time:		 5.20 secs
    Response time:		 0.51 secs
    Throughput:		         0.38 MB/sec

Uma diferença pequena a favor do Play, mas nada que faça crescer os olhos. E agora os números obtidos a partir da segunda simulação.

    Transactions:	       100 hits
    Availability:	       100.00 %
    Elapsed time:	       195.05 secs
    Response time:	       18.45 secs
    Throughput:		       1.00 MB/sec

Nesse momento você poderia parar e olhar que todos os números foram melhores, mas eu quero que você preste atenção para a disponibilidade. Ela ficou em 100%! e é isso que sua empresa mais vai querer quando sua aplicação tiver o pico de acesso.  Com esforço zero, sem precisar fazer nenhuma configuração adicional, sua aplicação está muito mais escalável do que a outra escrita com Servlet puro, imagine se usasse algum outro framework. O tempo gasto para atender o request é um pouco alto por conta da listagem de 100.000 transações.

Caso tenha ficado curioso em relação ao código, os mesmos podem ser encontrados aqui e aqui.

A maneira mais comum de fazer isso, até por conta da facilidade encontrada hoje em dia com as ferramentas de virtualização, é criar várias máquinas e fazer o deploy da sua aplicação nessas instâncias. Eu não vou contra isso, só vou contra a ideia disso ser uma das primeiras a coisas a se pensar. Até porque, quando você opta por essa abordagem, estratégias de replicação de sessão de usuário, deploy em vários servidores e outros detalhes terão que ser pensados. E os engenheiros das grandes aplicações do mundo nunca deixam de falar que um dos fatores de sucesso é a simplicidade e não a complexidade.

Ainda foi deixado de fora, toda parte de desenvolvimento que ele facilita para você. Diferenciação de ambientes, views compiladas, integração com o Akka para  a realização de tarefas assíncronas, desenvolvimento sem pausas por conta de alterações em classes ou arquivos de configuração.

Caso tenha gostado do que o Play demonstrou, assim como o Linkedin e o Coursera, não deixe de dar uma olhada no livro que eu escrevi sobre Play e lançado pela LeanPub.

Duck Typing aplicado no Scala

Nem me lembro a última vez que eu passei aqui… Estava aqui num projeto pessoal e achei um caso bem legal para o famoso Duck Typing. 

A minha situação é a seguinte. Tenho um método que tem que atualizar a localização de um objeto no banco. A assinatura do método tinha que ser mais ou menos assim:

   def update(crawledUrl: String, latitude: Double; longitude: Double)

O problema aqui é que eu quero receber um objeto que representa a localização. Normalmente, seria necessário criar uma classe para representar esse objeto. O que levaria o código a ficar assim:

  def update(crawledUrl: String, localizacao:MinhaLocalizaco) = {
         println(localizacao.getLatitude)
         println(localizacao.getLongitude)
  }

Só que na ponta onde eu invoco o método, preciso transformar a localização que vem da biblioteca para o meu objeto do tipo MinhaLocalizacao.  Na verdade não tem nenhum problema, só que demos uma volta meio grande para recebe-lo. Nesses cenários, ter uma linguagem a mais na sua caixa de ferramenta pode deixar o código mais flexível. Aqui está uma outra opção para a implementação do mesmo método.

  def update(crawledUrl: String, location: { def getLatitude: Double; def getLongitude: Double })

Perceba que eu pouco me importo com o tipo de objeto, o que eu defino é uma interface que exige os métodos getLatitude getLongitude. Não forço ninguém a criar nada, posso receber objeto de qualquer tipo, bem mais tranquilo. Isso é o que a galera chama no Scala de Structural TypingNo mundo de linguagens de script é chamado de Duck Typing. A invocação do método, que por sinal está em uma classe Java, segue abaixo:

   //getLocation retorna um objeto da biblioteca...
   dao.update(id, location.getGeometry().getLocation())

O único detalhe que saímos perdendo aqui, é que como a chamada do método está num método escrito em Java, não vai ter a checagem do tipo sendo passado. Então não rola uma garantia de compilação, o que é um ponto bem legal dessa abordagem no Scala. Se a chamada estivesse num código Scala, só seria permitido passar algum objeto que respondesse para os métodos necessários.

Bom, era isso. Já chegaram a usar Duck Typing nas outras linguagens? O que achou dessa solução? Poste aqui para o bem e para o mal.

Cuidado com sessions no heroku

Só uma passada rápida por aqui. Estava mexendo no Agendatech para melhorar o processo de participar de uma promoção ou de informar que a pessoa vai em um evento. O problema era o seguinte: quando você clicava no botão, a aplicação redirecionava o usuário para a página do twitter e na volta, mesmo com o usuário já logado, ele era obrigado a clicar novamente para participar da promoção.

A minha solução, não que tenha sido a melhor, foi guardar uma session com o evento e o tipo de botão que ele clicou e, na volta do login realizado no twitter, eu pego esse objeto que ficou guardado na session e faço a associação com o usuário que acabou de se logar. Dessa forma, ele não precisa clicar novamente para confirmar a participação, isso já fica sendo feito automaticamente.

O problema foi que eu guardei na session um objeto do tipo Evento, que é o principal do sistema. Por conta disso ele tem alguns relacionamentos, além dos atributos como data do evento, descrição, etc… Parece que o Heroku não gostou muito do tamanho do objeto que ele teve que serializar e começou a soltar uma exception do tipo CookieOverflow. A solução foi guardar apenas o id do evento na session :).

Bom, essa blogada é mais para eu sempre ficar com isso em mente. Quando você tá num ambiente de Cloud no estilo PAAS da vida, temos sempre que tomar cuidado quando o assunto é guardar coisas aleatorias no disco. Afinal de contas, isso não te pertence mais, pelo menos no plano básico :).

Getting into the new Scala’s 2.10 Reflection API

The newer version of Scala brings us some new features. In this post, Simon Ochsenreither listed many of these new things. One of  the most expected, at least for me,  is the new Reflection API. In my last project at Caelum, we faced a lot of problems using Java’s Reflection API to discover things that just existed in a Scala class. For example, we needed to know if a method was implicit or not and this information was not clearly pointed at the bytecode. In order to solve this problem, we had to use the scalap library and I can tell, the code is not beautiful.

So my point here is just that, show you how to use the new Reflection API to discover if a method is or not a implicit. The code must be a starting point to do whatever you might need with the rest of the API.

To get started I was looking for a way to get information about the class, such as methods implicitness, existence of companion objects and so on. So I created an Object with an implicit method just to test:

 object Pimps{
    implicit def pimp(str:String) = new {
       def test = println("hello")
    }
 }
 

Now I need to get information about this class, all the traits that you must know to work with Scala’s Reflection are at Scala’s github repository, and that was my starting point. The Mirror trait is the entry point of the api, its implementation can be found here. So let’s get started retrieving all the informations about our class. Here is the code:

val aType:Type = Mirror.typeOfInstance(Pimps)

Now we have the Type instance of our class. This object provides informations about your class, for example we can pick all the members. Let me show you the code:

 val members:List[Symbol] = aType.members
 

The Symbol trait is the abstraction of everything that you have in your class, constructors, methods, variables and the class declaration itself. And, at least for me, this was my savior. With an instance of Symbol is possible to get information about the Scala code. For instance, let’s filter all the Symbols that contains an implicit modifier in our Pimps class:

val justImplicits = members.filter(member => member.hasModifier(Modifier.`implicit`))

I think this is a good starting point to test the new API. All the code was tested in REPL with the 2.10 version, milestone 2. Also, there is a gist with the example code. Don’t forget the imports :).

Thanks to @adrianoalmeida7 for kindly reviewing this post.

Evitando Null Pointer Exception em Scala

No meu post anterior foi discutido uma maneira de tentar evitar os famigerados NPE nas aplicações escritas em Java. Atualmente, uma linguagem que tenho gostado bastante é Scala. Uma das idéias da linguagem é a de fornecer soluções prontas para problemas comuns que encontramos quando fazemos código em Java. Um exemplo muito bom disso é a idéia para evitar os NPEs.

Para exemplificar, será usada a mesma agenda que foi escrita no post anterior. Abaixo segue o código da agenda escrito em Scala:

 import scala.collection.mutable.Map
 class Agenda {
   private val contatos = Map[String,Contato]()
  //aqui adicionamos um contato no mapa usando o email como chave
   def adiciona (contato:Contato) {
        contatos += contato.email -> contato
   }
   def  buscaPor(email:String) = {
         if(contatos.contains(email)){
            contatos.get(email).get
         }
         else{
            null
         }
    }
 }

Aqui está sendo retornado o mesmo null que era retornado no post anterior. Vale salientar que dei uma forçada no código para deixar ele parecido com o escrito em Java. E o cliente segue abaixo:

 object TesteAgenda {
      def main(args : Array[String]) : Unit = {
             val agenda = new Agenda
  	     agenda.adiciona Contato("alberto","teste@teste.com.br")
 	     val contato = agenda buscaPor "teste2@teste.com.br"
             if(contato==null){
                  println("Nao foi achado")
             }
             else{
                  println(contato.nome)
             }
      }
 }

Para tentar evitar esse tipo de retorno, a linguagem já vem com uma implementação mais esperta do que a sugerida pelo Null Value Object e muito mais elegante do que a exibida no post anterior. A implementação está abaixo:

 def buscaPor(email:String):Option[Contato] = {
    if(contatos.contains(email)){
        Some(contatos.get(email).get)
    }
    else{
      None
    }
 }

Option é uma trait, que pode ser encarada como uma interface do Java, porém com mais poderes. Ela vem com duas implementações: Some(…), quando você quer indicar que algum objeto vai ser retornado e None para indicar que nada vai ser retornado. Agora no código cliente podemos usá-la da seguinte maneira:

  println(contato.getOrElse(Contato("nao encontrado", "email@email.com.br")).nome)

Dessa maneira é evitado o NPE a um custo bem pequeno. Sem a necessidade de herança ou implementações mais complexas, já está pronto :). E o método getOrElse faz o papel do if else que era feito antes.  O post de Tony Morris cita vários exemplos de uso dos métodos das Options, mostrando o que cada um faz por baixo do pano. O mais interessante é que a própria linguagem faz bastante uso de Options para resolver problemas.

O exemplo de buscar um valor no mapa é um caso típico de retornar uma Option, e o método get já foi implementado dessa forma.  Segue o código:

  def buscaPor(email:String) = contatos.get(email)

Pretendo continuar explorando a linguagem nos próximos posts do blog. Acredito que as possibilidades que ela nos traz durante o desenvolvimento do código valem bastante a pena.  Outros blogs a serem acompanhados, que vem escrevendo sobre Scala são os da Caelum e de Urubatan.

Uma abordagem para evitar NullPointerException

Invocar métodos que podem ou não retornar o objeto esperado é algo bem comum no nosso dia-a-dia de programação. Abaixo segue um exemplo bem simples:

public class Agenda {

private Map contatos = new HashMap();

public void adiciona(Contato contato) {
contatos.put(contato.getEmail(), contato);
}

public Contato buscaPor(String email){
return contatos.get(email);
}
}

O método que realiza a busca retorna o contato encontrado ou, no meu caso, retorna null caso não encontre nada. Agora imagine que temos uma classe que faz uso dessa agenda. Por exemplo a que segue abaixo:

public class TesteAgenda {

public static void main(String[] args) {
Agenda agenda = new Agenda();
agenda.adiciona(new Contato("alberto","teste@teste.com.br"));

Contato contato = agenda.buscaPor("teste2@teste.com.br");
System.out.println(contato.getNome());
}
}

Mesmo sendo um exemplo muito simples, caimos num problema bem comum. O método buscaPor(email) vai retornar null porque não encontrou nada e o cliente que está usando o código toma o velho NullPointerException. No caso exposto, o código que utiliza este tipo de método, e eles se espalham que nem uma praga pelo sistema, começa a defender-se utilizando as velhas checagens com ifs para verificar se o objeto retornado é null ou não. Abaixo o exemplo:

if(contato!=null){
System.out.println(contato.getNome());
}
else{
System.out.println("Não encontrado");
}

O grande mal dessa abordagem é que você tem que ficar lembrando o tempo todo de ter que verificar isso. Exato, o problema não é colocar os ifs, if ou não, algum código vai ter de ser colocado para verificar isso.

Uma abordagem para tentar minimizar o problema da lembrança é usar o pattern Null Object, onde um objeto com semântica Nula é retornado para o invocador do método. É uma maneira um pouco mais elegante de resolver o problema.  Por exemplo, para o caso da agenda, poderia fazer uma classe chamada ContatoNaoEncontrado. O exemplo segue abaixo:

public class ContatoNaoEncontrado extends Contato {

@Override
public String getNome() {
return "Não encontrado";
}

@Override
public String getEmail() {
return "Não encontrado";
}

}

Fariamos uma alteração no método buscaPor(email) para que faça a verificação, ficando com ele da seguinte forma:

public Contato buscaPor(String email){
Contato contato = contatos.get(email);
if(contato!=null){
return contato;
}
return new ContatoNaoEncontrado();
}

E no código que utiliza este método podemos substituir os ifs pelo classico polimorfismo:

Contato contato = agenda.buscaPor("teste2@teste.com.br");
System.out.println(contato.getNome());
System.out.println(contato.getEmail());

Caso a checagem ainda seja necessária, pode-se adicionar um método na classe mãe indicando se foi encontrado ou não. Dessa forma o Null Object sempre retornaria false. Aplicando essa alteração ficamos com o seguinte código:

if(contato.foiAchado()){
System.out.println("Achamos seu contato... => "+contato.getNome());
}
else{
System.out.println("Não foi possivel...");
}

O ponto, um tanto quanto questionavel, é o fato de usar herança para implementar o Null Object. Poderia ser utilizado a mesma classe setando tudo para os valores apropriados, mas aí seria perdido a idéia da semântica do objeto nulo.

Pelo menos na minha opinião, não existe uma regra certinha para desenvolver, a que tento seguir é a de sempre deixar o código mais auto-explicativo possivel e de fácil manutenção. Caso você tenha apenas um lugar para fazer a checagem do objeto nulo, é claro que não precisa gastar seu tempo implementando isso. Agora, se essa checagem começar a se espalhar muito, essa abordagem pode salvar você de tomar uns NPE pelo caminho. No próximo post vou mostrar a mesma abordagem utilizando a linguagem Scala, a qual já possui implementado uma abordagem para resolver este mesmo problema.