YAML e fixtures no Java
Publicado em Developer
dbassert fixtures java junit jyaml yaml
Esses dias precisei fazer alguns testes com o JUnit (sim, ainda trabalho com Java de maneira regular) e bateu uma saudade dos testes do Rails, especialmente dos recursos das fixtures, resolvi dar uma procurada no assunto e acabei encontrando o dbAssert, que de quebra me mostrou como utilizar YAML no Java com o JYaml. Pode até ser assunto batido para o pessoal mais punk em Java, mas para mim foi novidade, ainda mais pelo fato que nos últimos anos estou trabalhando muito mais com Ruby e Rails.
Com o JYaml ficou mais fácil armazenar algumas configurações. No site oficial tem algumas instruções para pegar resultados direto como uma classe customizada específica, mas para o que estava precisando aqui a Map já quebra um galhão. Eu precisava pegar configurações para conectar no banco de dados em um arquivo chamado data.yml, cujo conteúdo é esse:
1 mysql: 2 url: jdbc:mysql://localhost/test 3 username: test 4 password: test 5 driver: com.mysql.jdbc.Driver
Usando o JYaml, fazendo o download do .jar e inserindo-o no CLASSPATH, utilizei o seguinte código (usando import org.ho.yaml.*; antes):
14 Map data = (Map) Yaml.load(new File("data.yml")); 15 Map mysql = (Map) data.get("mysql"); 16 String username = (String) mysql.get("username"); 17 String password = (String) mysql.get("password"); 18 String driver = (String) mysql.get("driver"); 19 String url = (String) mysql.get("url");
Apesar de estar sem atualizações desde 2007 e haverem outras implementações de YAML em Java por aí, gostei do JYaml, ele atende minhas expectativas de forma simples.
Partindo agora para as fixtures, levando em conta uma classe chamada Customers (não mostrada aqui) para agir como um ORM bem simples, um arquivo de testes para o JUnit chamado TestCustomer.java e um minúsculo arquivo YAML chamado customers.yml com o seguinte conteúdo:
1 one: 2 id: 1 3 name: Antonio
Escrevi os testes da seguinte maneira, mostrando aqui o TestCustomer.java:
1 import java.io.*; 2 import java.util.*; 3 import junit.framework.*; 4 import junit.extensions.*; 5 import net.codemate.*; 6 import org.ho.yaml.*; 7 8 public class TestCustomer extends TestCase { 9 private static DbAssert dbAssert; 10 private static DbSource dbSource; 11 private static Fixture cust_fix; 12 private static Customers customers; 13 14 public TestCustomer(String name){ 15 super(name); 16 } 17 18 public static void testFixturesLoaded(){ 19 dbAssert.table("customers").where("id",1); 20 dbAssert.assert_not_empty("name"); 21 dbAssert.assert_column("name","Antonio"); 22 dbAssert.assert_count(1); 23 } 24 25 public static void testFirstCustomer() throws java.sql.SQLException { 26 Fixture first = (Fixture) cust_fix.get("one"); 27 assertEquals(first.get("id"),1); 28 assertEquals(first.get("name"),"Antonio"); 29 30 Customer c = customers.get(0); 31 assertEquals(c.getId(),first.get("id")); 32 assertEquals(c.getName(),first.get("name")); 33 } 34 35 public static void testAddCustomer() throws java.sql.SQLException { 36 int size = customers.size(); 37 Customer c = customers.add(2,"Antonia"); 38 dbAssert.table("customers"); 39 dbAssert.assert_count(2); 40 assertEquals(size+1,customers.size()); 41 } 42 43 public static Test suite(){ 44 TestSuite suite = new TestSuite(); 45 suite.addTest(new TestCustomer("testFixturesLoaded")); 46 suite.addTest(new TestCustomer("testFirstCustomer")); 47 suite.addTest(new TestCustomer("testAddCustomer")); 48 49 TestSetup wrapper = new TestSetup(suite){ 50 protected void setUp(){ 51 try { 52 dbAssert = DbAssert.init("data.yml"); 53 dbSource = dbAssert.source("mysql"); 54 cust_fix = dbSource.fixture("fixtures/customers.yml"); 55 customers = new Customers(); 56 }catch(Exception e){ 57 System.err.println("setup error: "+e.getMessage()); 58 } 59 } 60 protected void tearDown(){ 61 dbSource.clean_table("customers"); 62 } 63 }; 64 return wrapper; 65 } 66 }
Agora dando uma dissecada no bicho:
- O principal da integração com o dbAssert é feito no setUp da TestSuite: com DbAssert.init("data.yml"), indicamos qual arquivo que contém as configurações do banco. Depois, com o método source("mysql") indicamos qual configuração que queremos utilizar (é ali que podem ir as development, test e production da vida).
- Logo em seguida, é carregado o arquivo de fixtures com fixtures/customers.yml. O dbAssert até tem um método source onde você passa como segundo parâmetro um getClass() e ele pega por padrão o arquivo no diretório fixtures, mas ele tem um pequeno problema quando a classe não está relacionada com um pacote.
- No método testFixturesLoaded eu fiz uma consulta com uma condição à tabela customers com table("customers").where("id",1), verificando que a coluna nome não estava vazia com assert_not_empty("name"), comparei o valor da coluna com assert_column("name","Antonio") e verifiquei que o total de linhas retornado foi igual à 1 com assert_count(1).
- Para pegar apenas um valor das fixtures, como fazemos no Rails com coleção(:chave), podemos utilizar Fixture first = (Fixture) cust_fix.get("one") e comparar seus atributos com por exemplo assertEquals(first.get("id"),1). Logo abaixo comparei com os valores do objeto da classe Customers, que recupera os valores do banco de dados.
- E em testAddCustomer, inseri um valor direto no banco de dados de teste e comparei com o total dos registros retornados anteriormente, mais 1.
Existem mais algumas outras assertions na página do dbAssert, que apesar de simples é um software que está me quebrando um bom galho nos testes que estou fazendo atualmente no Java. Deixando claro que o código dos exemplos, como sempre nos posts, são orientados à didática e exposição da ferramenta. Quem precisar de funcionalidade e gostou, divirta-se! :-)
Comentários
Comentários fechados.
Artigos anteriores
- Pull requests em modo raiz - sex, 22 de dezembro de 2023, 09:57:09 -0300
- Qual a idade do seu repositório? - ter, 27 de dezembro de 2022, 12:50:35 -0300
- Utilizando ctags em projetos Rails mais recentes - qui, 24 de junho de 2021, 08:23:43 -0300
- Fazendo o seu projeto brotar - seg, 15 de julho de 2019, 08:57:05 -0300
- Learn Functional Programming with Elixir - sex, 02 de março de 2018, 18:47:13 -0300
- Ambiente mínimo - Driver Driven Development - qua, 23 de agosto de 2017, 15:15:03 -0300
- Ambiente mínimo - repositórios de código - dom, 16 de abril de 2017, 13:02:14 -0300
- Ambiente mínimo - terminal e navegador - dom, 02 de abril de 2017, 21:43:29 -0300
- Utilizando muitas gems no seu projeto? - sáb, 29 de outubro de 2016, 11:57:55 -0200
- Desenvolvedores e inteligência artificial - seg, 11 de julho de 2016, 09:09:38 -0300
kkkk acho engraçado estes caras que tentam demostrar que "Java é desatualizado" e que "Não se usa mais isso" kkkkkkkkkkkkkk
Thiago, vc é menino, e isso ficou claro no seu comentário.
Thiago, sim, é um sistema que já existia e não compensa reescrever tudo em Ruby ou Rails. Eu ia achar uma maravilha se o cliente me pagasse para fazer isso, mas acho que não vai rolar ehehe.
Mas nada contra Java também, se a situação mostrar que é mais adequado para determinada tarefa, eu uso de boa. :-)
Que mal não lhe pergunte, mas porquê que você ainda trabalha com Java? É algum sistema que já existia e que você dá manutenção ou o quê?..
Só curiosidade...