UaiMockServer – Muitas novidades para ajudar ainda mais em seus testes

Olá, tudo bem?

A nova versão do uaiMockServer tem diversas novas funcionalidades que vão revolucionar os frameworks open source que fazem papel de mock HTTP.

A primeira grande novidade é justamente uma tela que permite a edição dos seus requests:

Index

Index

Agora não será mais necessário você editar seus requests através de um tedioso arquivo de configuração, utilize a ferramenta gráfica que fará isso de modo simples e prático. Basta acessar a tela de edição pela URL: http://localhost:1234/uaiGui/index

Outra novidade é justamente poder identificar o que está sendo enviado e recebido no request de um modo prático. Basta ir na aba “Log” e disparar o request:

Request Log

Request Log

Ao detalhar um request com sucesso você poderá ver:

Success Request

Success Request

Ao detalhar um requets com erro você verá como:

Error Detail 01

Error Detail 01

Um detalhe interessante é que será possível ver o Log do Servidor, esse log ajudará analisar o que aconteceu de errado no request:

Error Detail 02

Error Detail 02

E por último, mas não menos importante, agora é possível utilizar Runner em seus testes com JUnit. Veja o exemplo abaixo:

UaiMockServer JUnit Runner

UaiMockServer JUnit Runner

Desse modo você não precisa mais fazer o controle manual do seu servidor. Você também pode especificar qual o arquivo de configuração a ser utilizado:

UaiMockServer JUnit Runner Configuration

UaiMockServer JUnit Runner Configuration

E para você que usa o Spring, você também pode utilizar o Runner especializado para o Spring:

UaiMockServer JUnit SpringRunner Configuration

UaiMockServer JUnit SpringRunner Configuration

Uma última alteração que foi necessário é fazer a troca do tipo do arquivo de configuração, infelizmente não é mais possível usar o arquivo do tipo HCON como na primeira versão. Agora o arquivo deve ser no formato JSON. Peço desculpas ao incômodo que isso possa causar, mas foi uma mudança para melhor.

O arquivo de configuração está como abaixo:

New Configuration File as JSON

New Configuration File as JSON

Uma vantagem em ter o arquivo de configuração em formato JSON é justamente de qualquer editor de texto poder formatar o código.

Site do projeto: http://uaimockserver.com

Código fonte: https://github.com/uaihebert/uaiMockServer

Versão standalone e arquivo de configuração: https://sourceforge.net/projects/uaimockserver/

Import do Maven:

<dependency>
    <groupId>uaihebert.com</groupId>
    <artifactId>uaiMockServer</artifactId>
    <version>1.1.0</version>
    <scope>test</scope>
</dependency>

Espero que você goste das novidades.

Qualquer dúvida ou sugestão, poste como comentário abaixo.

o_

UaiMockServer – A lot of new Features to help you with your tests

Hello, how are you?

The newest release of uaiMockVersion has a lot of new features that will influenciate a lot the HTTP mock open sources frameworks.

The first big feature is a GUI that will allow you to edit your requests:

Index

Index

You will not need to edit those boring configuration files anymore, all you need to do is to use access the GUI through the default url: http://localhost:1234/uaiGui/index

Another feature allows you to analyse everything in your request/response, very easily. All you need to do is to go to the Log tab and fire the request:

Request Log

Request Log

And if you detail a success request you will see:

Success Request

Success Request

And if you detail a request with error:

Error Detail 01

Error Detail 01

To help you to find out what kind of error just happened, you will be able to see the server log:

Error Detail 02

Error Detail 02

The last, but not least, feature is a JUnit runner that will control the server for you:

UaiMockServer JUnit Runner

UaiMockServer JUnit Runner

Using like the sample above you will not need to start and stop the uaiMockServer manually. Using like above the uaiMockServer will search for the default file named: uaiMockServer.json

You could also set specific config file:

UaiMockServer JUnit Runner Configuration

UaiMockServer JUnit Runner Configuration

And if you are a Spring user, you could also use the Spring Runner:

UaiMockServer JUnit SpringRunner Configuration

UaiMockServer JUnit SpringRunner Configuration

The last update in this new version was to change the config file from HCON to JSON. Unfortunately you will need to change your config file from HCON to JSON, sorry for that. I could not keep using the HCON type anymore.

The config file will look like below:

New Configuration File as JSON

New Configuration File as JSON

One advantage of the config file as JSON is that any file editor will be able to give you a better support.

The project site: http://uaimockserver.com/

Source code: https://github.com/uaihebert/uaiMockServer

Standalone version and config example: https://sourceforge.net/projects/uaimockserver/

Maven import:

<dependency>
    <groupId>uaihebert.com</groupId>
    <artifactId>uaiMockServer</artifactId>
    <version>1.1.0</version>
    <scope>test</scope>
</dependency>

I hope you liked the news.

If you have any questions/doubt/suggestion just post it below.

o_

uaiMockServer – Create a Mock Rest Server with a single command line

Hello how are you?

Have you ever needed to invoke a REST service, but this service was not created yet?

Imagine that you are developing an APP that needs to invoke an inexistent REST service. You will need to create a fake code that will be replaced once that the real code is finished. No matter if you are working with Java, .NET, PHP, Ruby, Python, etc. You will always need to create a fake invocation method if the REST service is not ready yet.

When we are programming in our unitary test we face the same problem. We will need to create a Mock code that will be invoked during the tests. The problem with this approach is that the real code is never invoked.

How can we solve this problem? Is there a solution that works for delphi, .NET, PHP, Java, Android, IOS, WindowsPhone, etc?

I present to you now my most recent creation: “uaiMockServer”.

With uaiMockServer you will be create a mock server using only a JAR file and a config file. With this server you will be able to execute real HTTP requests, but using your test data.

There are two ways of using uaiMockServer: Standalone and Unit Tests

Standalone

To use the uaiMockServer as a Standalone server you will manually type the command that starts it. Run the command in a prompt:

java -jar uaiMockServer-{VERSION}.Standalone.jar

You will only need the config file, that we will talk about very soon.

In the sample config file there is a mapping using the port 1234. If you are using linux, type the command:

curl localhost:1234/uaiMockServer/

The HTTP Response will contain a JSON.

Unit Test

First step is to add the project in your pom:

<dependency>
   <groupId>uaihebert.com</groupId>
   <artifactId>uaiMockServer</artifactId>
   <version>1.0.1</version>
   <scope>test</scope>
</dependency>

Now you can create a test code like:

public class YourTest {
    private static UaiMockServer uaiMockServer;
 
    @BeforeClass
    public static void beforeClass() {
        uaiMockServer = UaiMockServer.start();
    }
 
    @AfterClass
    public static void afterClass() {
        uaiMockServer.shutdown();
    }
 
    @Test
    public void aTest() {
        final Customer customer = // invoke the URL
        assertTrue(customer != null);
    }
}

You will be able to invoke the URL using any kind of framework. Below you will see a code sample using the RestEasy framework doing a request mapped in the sample config file (that we will see soon):

@Test
public void isGetRootReturning200() {
    final String url = "http://localhost:1234/uaiMockServer/";
 
    Client client = ClientBuilder.newClient();
    Response response = client.target(url).request().get();
 
    assertEquals(200, response.getStatus());
}

What is the gain in the test? You will not need a mock code anymore. You can fire a HTTP request from your JUnit test.

Configuration

To run the project you will need a config file. A simple sample would be like below:

com.uaihebert.uaimockserver {
    port = 1234
    host = localhost
    fileLog = false
    consoleLog = true
    context = /uaiMockServer
    defaultContentTypeResponse = "text/html;charset=UTF-8"
    routes = [
        {
            request {
                path = "/"
                method = "GET"
            }
            response {
                contentType = "application/json;charset=UTF-8"
                statusCode = 200
                body = """{"mockBody":{"title":"Hello World"}}"""
            }
        }
    ]
}

The file must have the .config extension and is not in the JSON format, but has a superset format of the JSON – HCON – used in configurations files (click here for more details).

With this file you can set up the port that will be invoked, the host, header, queryParm and other several options that are described in the uaiMockServer documentation.

Notice that in the configuration was created a request and a response; with these configurations you can mock every request that you want.

If you are going to use the Standalone version the config file must be in the same directory of the JAR file. You can set a different path with the command:

java -jar uaiMockServer-{VERSION}.Standalone.jar FULL_FILE_PATH

If you will run the project in your Unit Tests (like JUnit) you must put the config file in the “src/test/resources” maven folder. Or you can pass the full path like:

uaiMockServer = UaiMockServer.start(FULL_FILE_PATH);

It is free?

Yes, it is. Use it at your will.

Is open source? Yes: https://github.com/uaihebert/uaiMockServer

Where is the documentation? http://uaimockserver.com/

Where can I find the Standalone and the sample Config file: http://sourceforge.net/projects/uaimockserver/files/

It has any automated test? Yes, we have a lot of tests and we got 100% code coverage.

What about performance?

In the GIT there is a test that executes 300 requests in less than 2s.

Thanks to:

uaiMockServer – Crie um servidor Rest de teste com apenas uma linha de comando

Olá, tudo bem?

Sabe aquele momento em que você precisa chamar um serviço REST, mas esse serviço não está pronto ainda?

Imagine que você está desenvolvendo uma nova tela do APP que o serviço REST ainda não está pronto. Nesse caso você precisará ter um código falso em seu projeto, e esse código terá que ser substituído quando o serviço ficar pronto. Não importa se você trabalha com Java, .NET, PHP, Ruby, Python, etc.. Você terá que ter sempre o trabalho de primeiro criar o mock e depois criar a chamada real quando o serviço REST não estiver pronto.

Para testes unitários temos o mesmo problema, é comum termos uma classe com a implementação real e uma classe com um código falso. Na hora do teste é que a classe falsa é utilizada. O ruim dessa abordagem é que o código que executa a chamada nunca é testado.

Como podemos resolver esse problema? E o mais interessante: “existe uma solução que atenda delphi, .NET, PHP, Java, Android, IOS, WindowsPhone, etc?”

Apresento para vocês o mais novo produto que criei: “uaiMockServer

Com o uaiMockServer você poderá criar um servidor de teste utilizando o JAR e um arquivo de configuração. Com o uaiMockServer você poderá disparar os testes usando HTTP, mas com seus dados de testes.

Existem dois modos de utilizar o uaiMockServer: Standalone e com Testes Unitários.

Standalone

O modo standalone é quando você dispara o jar manualmente. Para executar o serviço manualmente basta fazer:

java -jar uaiMockServer-{VERSION}.Standalone.jar

Tudo o que você precisa agora é do arquivo de configuração que estará descrito mais abaixo.

No arquivo exemplo de configuração já vem mapeado um hello world apontando para a porta 1234. Se você estiver usando linux, execute o comando:

curl localhost:1234/uaiMockServer/

E você já verá o JSON retornado.

Testes Unitários

Primeiro passo é adicionar o projeto em seu pom:

<dependency>
   <groupId>uaihebert.com</groupId>
   <artifactId>uaiMockServer</artifactId>
   <version>1.0.1</version>
   <scope>test</scope>
</dependency>

Uma vez que a dependência já está em seu pom você pode criar um teste como o abaixo:

public class YourTest {
    private static UaiMockServer uaiMockServer;

    @BeforeClass
    public static void beforeClass() {
        uaiMockServer = UaiMockServer.start();
    }

    @AfterClass
    public static void afterClass() {
        uaiMockServer.shutdown();
    }

    @Test
    public void aTest() {
        final Customer customer = // invoke the URL
        assertTrue(customer != null);
    }
}

A chamada na URL tem que ser feita com algum framework de sua preferência. Eu coloco abaixo um exemplo feito utilizando RestEasy e o arquivo de configuração (mostrado mais abaixo):

@Test
public void isGetRootReturning200() {
    final String url = "http://localhost:1234/uaiMockServer/";

    Client client = ClientBuilder.newClient();
    Response response = client.target(url).request().get();

    assertEquals(200, response.getStatus());
}

A vantagem disso? Agora você não precisa mais de um código mock em seus testes. Você pode chamar diretamente do JUnit o servidor criado.

Configuração

Para rodar corretamente é necessário um arquivo de configuração. Um exemplo simples seria o arquivo abaixo:

com.uaihebert.uaimockserver {
	port = 1234
	host = localhost
	fileLog = false
	consoleLog = true
	context = /uaiMockServer
	defaultContentTypeResponse = "text/html;charset=UTF-8"
	routes = [
	    {
			request {
				path = "/"
				method = "GET"
			}
			response {
				contentType = "application/json;charset=UTF-8"
				statusCode = 200
				body = """{"mockBody":{"title":"Hello World"}}"""
			}
	    }
    ]
}

O arquivo tem que ter a extensão .config e não está no formato JSON, mas sim é um superset do JSON – HCON – utilizado para configurações (clique aqui para mais detalhes).

Com esse arquivo você pode configurar a porta a ser chamada, o host, header, queryparam e diversas outras funções que estão descritas na documentação do uaiMockServer.

Note que foi criado um request e response desse modo você pode simular toda chamada que você quiser.

Caso você rode a versão Standalone, esse arquivo deve ficar na mesma pasta que o jar. Você também pode passar o caminho completo assim:

java -jar uaiMockServer-{VERSION}.Standalone.jar CAMINHO_COMPLETO_DO_ARQUIVO

Caso você vá rodar o serviço em seus testes unitários (JUnit por exemplo), você deve colocar o arquivo na pasta “src/test/resources” do maven. Você também poderia passar o caminho completo do arquivo como:

uaiMockServer = UaiMockServer.start(CAMINHO_COMPLETO_DO_ARQUIVO);

É grátis?

Sim. Use a vontade.

O código fonte é aberto? Sim: https://github.com/uaihebert/uaiMockServer

A documentação está onde? http://uaimockserver.com

E para baixar o .config e o JAR Standalone? http://sourceforge.net/projects/uaimockserver/files/

Tem teste? Sim, Temos bastantes testes unitários e 100% de cobertura.

Performance desse trem é bom?

No próprio GIT tem um teste que dispara 300 requests e tem todas as resposta em menos de 2 segundos.

Agradecimentos Especiais

Be a Developer, not a Blender

Hello, how are you?

We live in a “frameworks that are easy to use” age that helps us to create our projects. One thing that a lot of teachers say is: “Just use this annotation and it will be ok”.

Annotations have the objective of making frameworks easier to use and identify their behavior, but some developers get lost with this feature and and they forget about some of the OO basics.

CRUD, JMS queues, Beans, transaction controls can be created in minutes, but what about the Object Orientation? What happened with the good practices that took a long time to be correctly forged? Why are they being abandoned?

Mixing Concepts

To understand better what I am trying to say, let us see below some code snippets  that we find in development sites. In the first sample we can see a code with JPA and JSON mixed:

@Entity
@XmlRootElement
@JsonAutoDetect
@DiscriminatorColumn(name = "animal_type")
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat"),
        @JsonSubTypes.Type(value = Bird.class, name = "bird")
})
public class Animal {
 
    @Id
    private int id;
 
    @JsonSerialize(using = JsonDateSerializer.class)
    private Date birthday;
 
    @JsonView(ToothView.class)
    @OneToMany(mappedBy = "animal")
    private List<Tooth> teethList;
 
    // other stuff
}
 
@Entity
@JsonRootName(value = "Dog")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Dog extends Animal {
 
    @JsonProperty
    private String name;
 
    @Convert(converter = JsonAttributeConverter.class)
    private Double weight;
 
    @JsonIgnore
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "dog", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Bone> boneList;
 
    public Dog() {
    }
}

What is the problem with the code above? Why would someone mix JSON annotations (VIEW) with JPA annotations (MODEL)? If we need to edit an attribute only to display it in a different way in a VIEW, this update will affect the same class that is used to persist the data. We will increase the risk to input a bug when persisting the data.

No Respect for the Layers

Let us see another example:

@ViewScoped
@ManagedBean
@TransactionManagement(TransactionManagementType.BEAN)
public class ManagedBeanOne extends SuperManagedBean implements Serializable {
     // attributes
    public String doSomething() {
        try{
            transaction.begin();
            // do something
            transaction.commit();
        }
        catch(Exception ex){
            transaction.rollback();
        }
    }
}
 
 
@ManagedBean
@WebService
@ViewScoped
public class ManagedBeanTwo implements Serializable{}

Should the class be defined as a JSF ManagedBean and an EJB? The worst part of this code is: Why is a JSF class managing a transaction? What do we gain by giving this ManagedBean so many responsibilities?

Huge Code Blocks Do Not Help

A code that I could not post here is a class with more than 1k lines. The worst part of a huge class is that the some developers start to make jokes about it, or sometimes the class is considered to be a huge bad monster that should never be touched because any update would break the code.

How long will developers keep adding just one if statement to this kind of classes without doing small refactorings?

Exception that Dictate the Rules

A terrible practice is using an Exception to handle the request flow. Take a look below:

try{
    myObject.doSomething();
} catch(MyExceptionOne one){
    sendErrorSmsToCustomer();
    defineOldPlanToCustomer();
    sentToScreenOne();
} catch(MyExceptionTwo two){
    sendErrorEmailToCustomer();
    defineNewPlanToCustomer();
    sentToScreenTwo();
}

What would happen with the database data if an error is thrown at the first line of the exception block? What would happen if a developer invokes “myObject.doSomething()” in another class but without the correct catch code like above? What if the line code that handles the user plan is not executed?

What comes next?

It is an easy task to say if code looks good or bad, but I believe that one thing that is needed is to always to show a solution. What we will see in the pages to come is not something created by me, but are good practices and design patterns that you will find in several development books.

What we will see:

  • Page 2: Do not Pass Over the Layers
    • Pay Attention to the Packages
  • Page 3: Increase your Cohesion
  • Page 4: Loose Coupling
    • Facade is a Good Call
  • Page 5: Let us Return to the DTOs World
    • How can I easily pass the Entity data to a DTO?
  • Page 6: Small Classes and Methods
  • Page 7: How can we use Exceptions Correctly?
  • Page 8: The Broken Window Theory
    • Keep your build working
    • Do not leave your tests breaking
    • Do not comment/ignore your tests
  • Page 9: Good practices that helps
    • KISS
    • DRY
  • Page 10: It does not matter if you have a huge amount of tests without quality
    • Use Test Tools
    • Did you find a bug? Create a test for it
  • Page 11: Conclusion

I hope that this posts helps you. (:

I am really thankful for the Rodrigo Sasaki’s (http://cv.rodrigosasaki.com) help, this guy rocks!

Seja um Desenvolvedor, não um liquidificador

Olá, tudo bem?

Vivemos em uma época onde é muito fácil de criar projetos com frameworks “mágicos”. O que é ensinado em diversos blogs e faculdades é que: “basta anotar com isso aqui que está pronto”.

Anotações tem a função de facilitar a utilização e a identificação de comportamentos dos frameworks, mas existem desenvolvedores que se perdem com essa facilidade e acabam esquecendo de conceitos básicos.

CRUD, filas JMS, Beans, controle de transações podem ser criados em minutos, mas e a parte de Orientação a Objeto? Conceitos básicos do Java? O que tem acontecido para que as boas práticas que demoraram anos para serem desenvolvidas simplesmente serem abandonadas?

Misturando Conceitos

Para ser mais claro, vamos ver alguns exemplos de códigos postados por desenvolvedores em fóruns. No primeiro exemplo é possível ver a mistura de JPA com JSON:

@Entity
@XmlRootElement
@JsonAutoDetect
@DiscriminatorColumn(name = "animal_type")
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat"),
        @JsonSubTypes.Type(value = Bird.class, name = "bird")
})
public class Animal {

    @Id
    private int id;

    @JsonSerialize(using = JsonDateSerializer.class)
    private Date birthday;

    @JsonView(ToothView.class)
    @OneToMany(mappedBy = "animal")
    private List<Tooth> teethList;

    // other stuff
}

@Entity
@JsonRootName(value = "Dog")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Dog extends Animal {

    @JsonProperty
    private String name;

    @Convert(converter = JsonAttributeConverter.class)
    private Double weight;

    @JsonIgnore
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "dog", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Bone> boneList;

    public Dog() {
    }
}

Qual o problema do código acima? Qual o motivo da mistura de anotações de JSON (view) com anotações do JPA (modelo)? Note que, por causa dessa mistura, qualquer campo que a view deva exibir de modo diferente afetará justamente a mesma classe utilizada para salvar dados no banco de dados.

Não respeitando as camadas

Vamos a outro exemplo:

@ViewScoped
@ManagedBean
@TransactionManagement(TransactionManagementType.BEAN)
public class ManagedBeanOne extends SuperManagedBean implements Serializable {
     // attributes
    public String doSomething() {
        try{
            transaction.begin(); 
            // do something
            transaction.commit();
        }
        catch(Exception ex){
            transaction.rollback();
        }
    }
}


@ManagedBean
@WebService
@ViewScoped
public class ManagedBeanTwo implements Serializable{}

Por que fazer de um ManagedBean de JSF também como um EJB? E até pior, por que deixar que um ManagedBean controle uma transação? Qual o ganho em deixar o ManagedBean com diversas responsabilidades?

Tamanho mais atrapalha que ajuda

Um exemplo que eu não tive como colocar aqui foi de uma classe com mais de 1k de linhas. A pior parte é saber que esse tipo de classe fica sempre como motivo de chacota, ou essa classe é tratada como um objeto de terror e espanto pois qualquer alteração quebra o sistema.

Até quando os desenvolvedores vão ter o hábito de sempre querer adicionar um if sem antes fazer um pequeno refactoring?

Exception que é Chefe

Outra prática terrível é deixar uma exceção controlar o fluxo. Veja como é fácil cometer esse erro:

try{
    myObject.doSomething();
} catch(MyExceptionOne one){
    sendErrorSmsToCustomer();
    defineOldPlanToCustomer();
    sentToScreenOne();
} catch(MyExceptionTwo two){
    sendErrorEmailToCustomer();
    defineNewPlanToCustomer();
    sentToScreenTwo();
}

No exemplo acima, o que aconteceria com os dados do banco se na primeira linha de uma exceção acontecesse um erro? O que aconteceria se algum desenvolvedor fosse executar a chamada myObject.doSomething(); em alguma outra classe, e não tratasse todos os erros como no exemplo acima? E se ele não adicionasse a linha onde não trata o plano do usuário?

E agora?

Falar dos problemas é fácil, mas eu creio que ser necessário mostrar soluções que podemos aplicar em nosso dia a dia para melhorar a qualidade de código. O que vamos ver nas próximas páginas não é nada inventado por mim, mas são práticas extraídas de livros sobre design patterns e boas práticas de programação.

O que veremos:

  • Página 2: Não transpasse camadas
    • Atenção nos pacotes
  • Página 3: Aumente a coesão
  • Página 4: Reduza o acoplamento
    • Facade é uma boa pedida
  • Página 5: Voltemos ao mundo dos DTOs
    • Como facilitar a cópia de uma Entity para um DTO
  • Página 6: Métodos e Classes pequenas
  • Página 7: Como usar exceção corretamente?
  • Página 8: Teoria da Janela quebrada
    • Mantenha seu build sempre funcionando
    • Nunca deixe testes quebrados
    • Não comente/ignore seus testes
  • Página 9: Boas práticas que ajudam
    • KISS
    • DRY
  • Página 10: Quantidade de testes não importa, mas sim a qualidade
    • Utilize ferramentas
    • Achou um bug? Crie um teste
  • Página 11: Conclusão

Espero que este post seja útil ao seu dia a dia. (:

Não poderia deixar de agradecer ao Rodrigo Sasaki (http://cv.rodrigosasaki.com/) que me deu uma força absurda na revisão do post.