XStream é a maneira mais fácil de trabalhar com XML em Java. Para trabalhar com JSON então, é ainda mais facil
XStream é a maneira mais fácil de trabalhar com XML em Java. Para trabalhar com JSON então, é ainda mais facil
Lendo sobre testes unitarios, imagine o caso onde o seu teste é complexo: um objeto que chama outro e, então, realiza as suas tarefas. Um bom caso é um DAO que acessa o banco de dados para fazer alguma coisa: se vc pensa em testar esse codigo de forma unitaria teria que subir um banco de testes e, se encontrasse um problema, poderia ser dificil dizer se é problema do DAO ou dos objetos que ele depende (como a conexão com o banco, ou o banco em si).
A solução para estes casos pode ser trabalhar com mocks: objetos “burros” que podem não ter nenhuma função alem de responder ao que vc especificou. A abordagem mais utilizada é vc programar estes objetos para responder a um ou mais metodos com argumentos especificos, assim como as respostas esperadas. No caso do DAO eu posso esperar um determinado SQL e especificar uma determinada resposta, tudo de acordo com o meu cenario de teste.
É claro que Mock Objects em excesso podem atrapalhar, mas é tudo uma questão de bom senso: costumo dizer para quem esta começando a focar os testes nas partes mais importantes do sistema, o core do modelo e regras de negocio e, então, incrementar estas praticas caso veja necessidade. Sem falar que volta e meia surge algo novo.
Para java existe o excelente framework JMock. Logo de cara o site oficial traz um exemplo de como utilizar um mock bem simples (incluindo a integração do mesmo com JUnit 4)
http://www.jmock.org/getting-started.html
Para entender, imagine esta interface
interface Subscriber { void receive(String message); }
Imagine que eu tenho um objeto do tipo Publisher que, ao invocar o metodo publish(message), ele envie esta mensagem para um Subscriber (que recebe com o metodo acima). Para testar o publish eu teria que me certificar que o metodo receive deste objeto Subscriber foi invocado com a mensagem especificada, mais ou menos assim:
import org.jmock.integration.junit4.JMock; import org.jmock.integration.junit4.JUnit4Mockery; import org.jmock.Expectations; @RunWith(JMock.class) class PublisherTest { Mockery context = new JUnit4Mockery(); @Test public void oneSubscriberReceivesAMessage() { // set up final Subscriber subscriber = context.mock(Subscriber.class); Publisher publisher = new Publisher(); // objeto que vou testar publisher.add(subscriber); // tenho que adicionar o mock! final String message = "message"; // aqui eu programo o que eu espero do teste context.checking(new Expectations() {{ oneOf (subscriber).receive(message); }}); // aqui eu executo! publisher.publish(message); } }
Facil?
Quem nunca passou por isso: ter que gerar e/ou ler arquivos xml e teve que escolher dentre diversas tecnologias e frameworks diferentes. Seja carregar tudo pra memoria ou ler aos poucos, se é um parser push ou pull, etc, é possivel dizer que para cada situação existe uma boa escolha.
Se o seu caso é trabalhar com arquivos cujos elementos podem ser mapeados em objetos java, uma boa escolha é o XStream
XStream xstream = new XStream(new DomDriver()); Person pac = new Person("Tiago", "Pac Man"); String xml = xstream.toXML(pac); /* Simples. É, para fazer o contrario, basta */ Person newPac = (Person)xstream.fromXML(xml);
Este e outros exemplos podem ser conferidos aqui:
http://xstream.codehaus.org/tutorial.html
É claro que o xml gerado assim, cru, nem sempre serve. Para isso vamos usar algumas linhas a mais para trabalhar com os recursos de alias, annotations e os Converters.
xtream.alias("pessoa",Person.class);
Dessa forma, para se livrar do nome.do.pacode.Person e trabalhar com algo mais expressivo como pessoa, basta adicionar este alias antes de converter de/para xml. Para trabalhar com aliasing de atributos (e coleções implicitas) o ponto de partida é este:
http://xstream.codehaus.org/alias-tutorial.html
É possivel trabalhar com annotations no seu modelo de classes, evitando toda essa configuração manual
http://xstream.codehaus.org/annotations-tutorial.html
Para trabalhar com o maximo de flexibilidade do XStream, entretanto, vc precisa trabalhar com Converters – Veja o exemplo da classe Birthday
http://xstream.codehaus.org/converter-tutorial.html
XStream trabalha muito bem com classes imutaveis, pois não recria os objetos usando o construtor e sim de maneira semelhante ao mecanismo de serialização de objetos, fazendo um bypass do construtor. Sem falar que traz um pensamento menos voltado a “tags” e mais OO.
Estes dias eu estava pensando nos reais custos de adotar uma nova tecnologia. Imagine que vc sempre trabalhou com Java e tem que trabalhar com .Net, o que causou essa escolha? Que estratégia existe por trás?
Bom, o principal custo esta vinculado com a capacidade de um time ou equipe de entregar, ou não, uma determinada release. Entra ai a curva de aprendizado, que não pode ser encarado como aprender a sintaxe de uma linguagem e sim compreender os fundamentos da mesma, bem como entender a infra-estrutura necessária para que ela desenvolva o seu papel.
Quem aprendeu PHP sabe como desenvolver uma pagina dinâmica, trabalhar com formularios, sessão e acesso a banco de dados, porém sabe que basta editar um arquivo e subir para o servidor que ele é ‘executado’. Passar para um mundo J2EE onde vc tem uma estrutura de diretórios para respeitar, arquivos de configuração e, principalmente, entender a filosofia J2EE, a diferença entre os servidores de aplicação, as particularidades do garbage collector, etc, enfim, não é uma tarefa simples.
Imagine que vc tem 2 semanas para desenvolver uma aplicação: o que vc escolheria? Antes de pensar “ah, 2 semanas, pra web eu faria em Rails”, pense que vc tem que desenvolver um uma equipe que não conhece Rails. Nesse caso, 2 semanas pode ser tempo muito curto para se comprometer com uma entrega se vc pensa em termos de Scrumm por exemplo, pois o time não conhece a sua velocidade (e, nesse caso, não importa velocidade pois vc TEM que terminar o projeto no prazo). Se a equipe inteira conhece PHP, metade conhece Java e apenas um cara conhece Ruby on Rails, seria interessante considerar PHP pois essa experiência acumulada colabora para a solução do problema: entregar software funcionando numa determinada data.
Quando temos liberdade de escolha e tempo necessário, podemos explorar outras linguagens, frameworks e tecnologias, usando alguns Sprints para desenvolver a habilidade necessária de implementar e, principalmente, de dar manutenção.
Outro ponto importante é a testabilidade do codigo: se vc não tem uma equipe com proficiência em testes unitários, cobrar num projeto com prazo curto pode ser um tiro no pé pois prazo curso geralmente detona o humor dos envolvidos, prejudicando a adoção de novas ideias. Um projeto de tres meses, por exemplo, seria ideal pois eu posso usar um dia (ou parte dele) para efetuar um pequeno workshop ou dojo sobre TDD e tecnologias de teste, se necessário. E o ideal é começar com testes pois codigo legado nem sempre é facil de injetar testabilidade (e as vezes deixa de funcionar no processo, ai o telefone toca, vem um esporro, é lindo).
Passei por uma situação curiosa certa vez: um serviço crítico seria adicionado à uma api de serviços com algum tempo de vida. Como ninguem sabia como testar direito usando PHP (criar mocks não é tão simples, pelo menos naquela época), desenvolvi um pequeno script que efetuava testes funcionais: eu utilizava aquele serviço usando todas as combinações possiveis de parâmetros e situações.
O grande problema dessa abordagem é desenvolver algo que pode receber atualizações: naquele momento eu tinha criado um modelo de forma a descrever os testes como estruturas de dados, assim bastaria adicioanr novas estruturas que eu teria, de forma simples, novos testes. Testes automatizados são uma tecnologia que pode agregar qualidade e, portanto, tem um custo também. Não vou ser fatalista e dizer que software sem suite de testes não tem qualidade (vide um hello world), mas vc pode atingir um patamar de qualidade superior com uma suite de testes completa, tanto por causa dela quanto pela mudança cognitiva que isso acarreta. Eu explico: desenvolver testes muda a forma como programamos. Não precisa ser TDD ou BDD: basta programar com atenção e esmero, este ultimo o grande responsável pelo sucesso de um projeto.
O desafio agora é desenvolver scripts de teste no estilo Cucumber/RSpec. Falarei disso no futuro, ainda mais que estou reinventado a roda – mas por um bom motivo.