No artigo anterior eu comecei a falar de testes com Spring, TestNG,
Mockito e Maven. Neste, vou continuar com o assunto. Agora direto
ao código e com exemplo práticos, usarei isto para discutir mais sobre
o tema.
Vamos ao código, então. Vou mostrar primeiro o código do
domínio e depois os serviços para, por fim, chegar no nosso objetivo: os
testes.
Produto
package com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain;
import java.io.Serializable;
/**
* Pojo que representa a entidade Produto.
* O produto pode ser qualquer mercadoria que eh vendida pelo estabelecimento.
* Você pode adicionar mapeamento ORM aqui com anotações por exemplo, isso foi
* abstraido por conta do foco do post.
*
* @author Diego Pacheco
* @version 1.0
* @since 28/07/2009
*
*/
public class Produto implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String nome;
private String desc;
public Produto(){ }
public Produto(Long id, String nome, String desc) {
super();
this.id = id;
this.nome = nome;
this.desc = desc;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String toString(){
return "id: " + id + ", nome: " + nome + ", descricao: " + desc;
}
}
Item
package com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain;
import java.io.Serializable;
/**
* Pojo que representa a entidade Item. Este eh soh um exemplo de modelagem, você poderia modelar de outras formas. Nesta caso
* o valor do produto e o preco ficam no item, assim podemos lidar com precos promocionais e vendas em lote.
*
* Você pode adicionar mapeamento ORM aqui com anotações por exemplo, isso foi
* abstraido por conta do foco do post.
*
* @author Diego Pacheco
* @version 1.0
* @since 28/07/2009
*
*/
public class Item implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Produto produto;
private Integer quantidade;
private Double preco;
public Item() {
super();
}
public Item(Long id,Produto produto, Integer quantidade, Double preco) {
super();
this.id = id;
this.produto = produto;
this.quantidade = quantidade;
this.preco = preco;
}
public Produto getProduto() {
return produto;
}
public void setProduto(Produto produto) {
this.produto = produto;
}
public Integer getQuantidade() {
return quantidade;
}
public void setQuantidade(Integer quantidade) {
this.quantidade = quantidade;
}
public Double getPreco() {
return preco;
}
public void setPreco(Double preco) {
this.preco = preco;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String toString(){
return "Produto: {" + produto + "}, quantidade: " + quantidade + ", preco: " + preco;
}
}
Vendedor
package com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain;
import java.io.Serializable;
/**
* Pojo que representa a entidade Vendedor.
* O Vendedor eh quem vende os produtos.
* Você pode adicionar mapeamento ORM aqui com anotações por exemplo, isso foi
* abstraido por conta do foco do post.
*
* @author Diego Pacheco
* @version 1.0
* @since 28/07/2009
*
*/
public class Vendedor implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String nome;
public Vendedor() {
super();
}
public Vendedor(Long id, String nome) {
super();
this.id = id;
this.nome = nome;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String toString(){
return "id: " + id + ", nome: " + nome;
}
}
Comissao
package com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain;
/**
* Pojo que representa a entidade Comissao. A sua resposabilidade eh de
* representar a comissao de uma venda.
*
* @author Diego Pacheco
* @version 1.0
* @since 28/07/2009
*
*/
public class Comissao {
private Long id;
private Venda venda;
private Double valor;
public Comissao() {
super();
}
public Comissao(Long id, Venda venda, Double valor) {
super();
this.id = id;
this.venda = venda;
this.valor = valor;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Venda getVenda() {
return venda;
}
public void setVenda(Venda venda) {
this.venda = venda;
}
public Double getValor() {
return valor;
}
public void setValor(Double valor) {
this.valor = valor;
}
}
Venda
package com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain;
import java.io.Serializable;
import java.util.List;
/**
* Pojo que representa a entidade Venda. Este eh soh um exemplo de modelagem, você poderia modelar de outras formas. Nesta caso
* o pojo Venda tem relacao com o Vendedor e uma lista de Item.
*
* Você pode adicionar mapeamento ORM aqui com anotações por exemplo, isso foi
* abstraido por conta do foco do post.
*
* @author Diego Pacheco
* @version 1.0
* @since 28/07/2009
*
*/
public class Venda implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private List<item> items;
private Vendedor vendedor;
public Venda() {
super();
}
public Venda(Long id, List<item> items, Vendedor vendedor) {
super();
this.id = id;
this.items = items;
this.vendedor = vendedor;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<item> getItems() {
return items;
}
public void setItems(List<item> items) {
this.items = items;
}
public Vendedor getVendedor() {
return vendedor;
}
public void setVendedor(Vendedor vendedor) {
this.vendedor = vendedor;
}
public String toSring(){
return "id: " + id + ", Items: {" + items + "}, vendedor: {" + vendedor + "}";
}
}
Se você caiu aqui de
para-quedas, pode conferir o artigo anterior, que tem uma explicação
mais detalhada sobre este domínio. Vamos ao código dos serviços. Estes,
sim, irei explicar mais detalhadamente agora.
ItemService
package com.blogspost.diegopacheco.testng.spring.mockito.maven.core.service;
import com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain.Item;
/**
* Contrato do service de Item. Neste caso eh resposável por dar baixa ao estoque.
*
* @author Diego Pacheco
* @version 1.0
* @since 28/07/2009
*
*/
public interface ItemService {
public void baixarEstoque(Item i);
}
Este
serviço opera sobre o Item. Neste exemplo ele define o contrato para
operação de dar baixa no estoque do item. Caso o item em questão, ao ser
baixado, não exista mais no estoque, o serviço deve lançar uma exception.
Neste
exemplo vamos supor que não existe implementação para o serviço de
itens, porem você tem que implementar o serviço de Vendas e além de
implementar vou mostrar como testar o mesmo.
Então vamos ver o
código do serviço de Vendas, primeiro começando pelo contrato (interface)
e depois indo para a implementação padrão.
VendaService
package com.blogspost.diegopacheco.testng.spring.mockito.maven.core.service;
import com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain.Comissao;
import com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain.Venda;
/**
* Contrato do service de Vendas. Que deve ser capaz de realizar uma venda e bem como estornar a mesma.
*
* @author Diego Pacheco
* @version 1.0
* @since 28/07/2009
*
*/
public interface VendaService {
public Comissao vender(Venda v);
public void estornar(Venda v);
}
Como podem
ver, quem implementar o contrato do serviço de vendas deverá implementar
estes dois métodos, sendo que o método estornar vai ser implementado
somente na próxima versão. Para esta versão você deverá implementar
o método vender.
Então vamos à implementação deste serviço com Spring e anotações, sempre usando e abusando na injeção de dependências.
VendaServiceImpl
package com.blogspost.diegopacheco.testng.spring.mockito.maven.core.service;
import org.springframework.stereotype.Component;
import com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain.Comissao;
import com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain.Item;
import com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain.Venda;
/**
* Implementacao padrao do service de vendas. Este service eh basico, ele acessa outros services
* para dar baixa do estoque e realizar comicionamento por exemplo.
*
* @author Diego Pacheco
* @version 1.0
* @since 28/07/2009
*
*/
@Component
public class VendaServiceImpl implements VendaService{
private ItemService itemService;
@Override
public Comissao vender(Venda v) {
// Criticas básicas do service.
if (v==null)
throw new IllegalArgumentException("A venda nao pode ser nula. ");
if(v.getVendedor()==null)
throw new IllegalArgumentException("A venda deve ter um vendedor. Vendedor nao pode ser nulo. ");
if(v.getItems()==null || v.getItems().size()==0)
throw new IllegalArgumentException("A venda deve possuir produtos. Produtos nulos. ");
// RN002 - Calcular total da venda para comicionamento.
Double total = 0.0;
for(Item i: v.getItems()){
total += (i.getPreco() * i.getQuantidade());
// RN001 - Dar baixa do estoque se possivel, e nao abortar venda.
itemService.baixarEstoque(i);
}
Comissao c = new Comissao();
c.setId(v.getId());
c.setValor(total/2);
c.setVenda(v);
return c;
}
@Override
public void estornar(Venda v) {
throw new UnsupportedOperationException("O metodo estornar. Vai ser implementado na versao 2.0 ");
}
public ItemService getItemService() {
return itemService;
}
public void setItemService(ItemService itemService) {
this.itemService = itemService;
}
}
Neste
serviço estou implementado as duas regras de negócio fictícias desta
aplicação. Como você pode reparar, estou utilizando a interface do serviço de
vendas, mesmo que existisse uma implementação, o certo é usar sempre a
interface. Perceba que no meio da regra de negócio do meu serviço de
vendas eu dependo de uma chamada do serviço de item que por sinal não
existe ainda.
Ok. Agora vamos ao setup neceário no maven para
utilziar Spring, TestNG e Mockito. Vou mostrar as dependêncdias no
pom.xml e depois a configuração do plugin do maven para integração com
TestNG.
Dependências do pom.xml
<dependencies>
<!-- Dependências apenas para os testes -->
<dependency>
<groupid>org.testng</groupid>
<artifactid>testng</artifactid>
<version>5.8</version>
<classifier>jdk15</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-test</artifactid>
<version>2.5.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-context</artifactid>
<version>2.5.6</version>
</dependency>
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-aop</artifactid>
<version>2.5.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-aspects</artifactid>
<version>2.5.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-beans</artifactid>
<version>2.5.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupid>org.aspectj</groupid>
<artifactid>aspectjrt</artifactid>
<version>1.5.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupid>org.aspectj</groupid>
<artifactid>aspectjweaver</artifactid>
<version>1.5.4</version>
<scope>test</scope>
</dependency>
</dependencies>
Como já disse
no post anterior, esta aplicação é reduzida, além disso o foco do post
são os testes e como configurar e executar os mesmos em um projeto Java
com Spring. Mas para isso eu tive que fornecer o mínimo de imformações
sobre a aplicação de exemplo para que possamos chegar nos testes.
Certo. Vamos à configuração do plugin do Maven…
<build>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-surefire-plugin</artifactid>
<version>2.4</version>
<configuration>
<suitexmlfiles>
<suitexmlfile>${basedir}/src/test/resources/testng.xml
</suitexmlfile>
</suitexmlfiles>
</configuration>
</plugin>
Este
é o plugin de relatórios do maven, estou integrando ele às configurações
do testNG. Este arquivo, chamado de testing.xml, é onde ficam as
configurações dos suites de testes.
Confira o conteúdo do arquivo abaixo:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="V.1.0" verbose="5">
<test name="RN001_RN002">
<packages>
<package name="com.blogspost.diegopacheco.testng.spring.mockito.maven.core.service.test">
</packages>
</test>
</suite>
O que são os Suites de testes do TestNG ?
São
as configurações para rodar testes em grupos. Isto é muito útil pois
você pode estar desenvolvendo mais de uma versão da sua aplicação ao
mesmo tempo. Já vi casos em que 3 versões são desenvolvidas ao mesmo
tempo. Logo é muito útil para o desenvolvedor poder testar apenas o que
é da sua versão.
Com o arquivo testing.xml eu configurei um test
suite para a versão 1.0 da aplicação. Você pode ter vários suites e
organizá-los de diversas formas, por exemplo: por versão, requisitos,
funcionalidades, interação/sprint, riscos, etc…
Ainda é possível colocar o mesmo teste em mais de um suite.
O
Maven vai executar os testes unitários do testNG dentro do seu cliclo
de vida principal, ou seja, quando você rodar o comando: $ mvn clean install
ele já vai rodar os testes. Se por acaso algum dos testes venham a
falhar, o build é abortado e o deploy ou package não é feito.
Este
tipo de comportamento é excelente e muito utilizado em soluções de
integração contínua, porque se os seus testes têm problemas, sua
aplicação não está pronta para produção, com esse mecanismo o maven
ajuda que você não libere uma aplicação com problemas nos testes.
Enfim,
agora podemos ir para os testes… Piomeiro vou mostrar como criar uma
classe de testes unitários usando Spring e TestNG, no próximo artigo vou
entrar mais fundo nos testes e no Mockito.
Como esta aplicação
é baseada em Spring, vamos ao arquivo de configuração do contexto do
Spring, neste caso a aplicação é orientada a anotações, então o arquivo
é simples mesmo.
spring-test-beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xsi="http://www.w3.org/2001/XMLSchema-instance" p="http://www.springframework.org/schema/p" aop="http://www.springframework.org/schema/aop" context="http://www.springframework.org/schema/context" jee="http://www.springframework.org/schema/jee" tx="http://www.springframework.org/schema/tx" schemalocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:annotation-config>
<context:spring-configured>
<context:component-scan package="com.blogspost.diegopacheco.testng" config="true">
<aop:aspectj-autoproxy>
</beans>
Este arquivo
está informando para o Spring que ele deve fazer uma varredura no
pacote com.blogspost.diegopacheco.testng e sub-pacotes procurando por
componentes do Spring. Isso é uma mão na roda e aumenta
consideravelmente a produtividade de sua equipe.
Agora vamos a nossa primeira implementação de testes unitários com o TestNG e o Spring.
VendaServiceSimplesTestNGTest
package com.blogspost.diegopacheco.testng.spring.mockito.maven.core.service.test;
import static org.testng.Assert.assertNotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;
import com.blogspost.diegopacheco.testng.spring.mockito.maven.core.domain.Venda;
import com.blogspost.diegopacheco.testng.spring.mockito.maven.core.service.VendaService;
/**
* Classe de testes para o Service de Vendas. Utilizando TestNG apénas.
*
* @author Diego Pacheco
* @version 1.0
* @since 30/06/2009
*
*/
@Test(groups={"V.1.0"})
@ContextConfiguration(locations={"/spring-test-beans.xml"})
public class VendaServiceSimplesTestNGTest extends AbstractTestNGSpringContextTests {
private VendaService vs;
public void testInjecaoSpring(){
assertNotNull(vs,"O VendaService Não pdoe ser null");
}
@Test(expectedExceptions=IllegalArgumentException.class)
public void testParametroVendaNull(){
vs.vender(null);
}
@Test(expectedExceptions=IllegalArgumentException.class)
public void testParametroVendedorNull(){
Venda v = new Venda();
vs.vender(v);
}
@Autowired
@Test(enabled=false)
public void setVs(VendaService vs) {
this.vs = vs;
}
}
Tenho muito o
que explicar sobre esta classe… Então, vamos por partes. Primeiro
sobre as anotações que existem no topo da classe.
- @Test(groups={“V.1.0”}):
Indica que é um teste do TestNG referente à primeira versão da
aplicação. Poderia ser outro grupo qualquer conforme dito antes. - @ContextConfiguration(locations={“/spring-test-beans.xml”}): Aqui estou dizendo para o Spring ser criado com este arquivo de configuração.
Perceba
que a nossa classe estende outra classe que é do Spring,
AbstractTestNGSpringContextTests é responsável por integrar o contexto do
Spring para testes com o TestNG.
Depois vocês podem ver que existe a propriedade VendaService e um método setter com as seguintes anotações:
- @Autowired: Indica que o Spring deve injetar um serviço de vendas, neste caso será VendaServiceImpl.
- @Test(enabled=false): Para indicar que este método não deve ser testado.
Sobre
a anotação @Test, se você usa testNG sozinho, cada método que você quer
testar deve ter esta anotação por exemplo, neste caso esta anotação vou
utilizando apenas no método que não quero testar, que é o método setter
chamado setVs.
Como estamos estendendo AbstractTestNGSpringContextTests, todos os método plublicos da classe serão testados.
Agora vamos falar um pouco mais sobre os 3 métodos de testes, que são eles:
- testInjecaoSpring
- testParametroVendaNull
- testParametroVendedorNull
O
primeiro método testInjecaoSpring testa se o Spring inetou uma
instáncia do Serviço de Datas, isto é mais para ajudar na prevenção de
pequenos erros do que no teste da aplicação mesmo. Neste método ainda
você deve ter reparado o sequinte código:
assertNotNull(vs,"O VendaService Não pdoe ser null");
Vamos por partes. O método assertNotNull vem do import estático feito no início da classe para:
import
static org.testng.Assert.assertNotNull. Ele testa se ‘vs’ é diferente
de null, caso ‘vs’ seja igual a null uma excpetion será levantada e o
teste irá falhar com a seguinte mensagem “O VendaService Não pode ser
null”.
Esta é a maneira adequade de se testar, usando asserções
que são verificações que dizem se o método que implementamos está
retornando ou está realizando o comportamento que deveria fazer.
Neste
momento o leitor pode achar que estou entrando em contradição, pois eu
disse que não era necessário a anotação @Test, porém os dois outros
métodos de testes têm ela, isso tem um motivo.
No método
testParametroVendaNull estou chamando o serviço de vendas passando
null, se reparar no início do código deste serviço, vai ver que existem
alguma críticas, e uma delas é se o objeto vendas é != null. Neste caso
não é, logo o correto é que o serviço levante uma exception do tipo
IllegalArgumentException, se ele não levantar esta exception é porque está
errado, pois passamos um argumento errado e ele aceitou. Ele levantando
uma excpetion, o teste está correto, pois é isto que esperamos.
O
mesmo ocorre para o terceiro método o testParametroVendedorNull só que
aqui testamos o cenário do vendedor ser nullo. Neste caso existe o
objeto venda, mas o objeto vendedor não. Logo também é esperada uma
exception.
Outro ponto importante é a nomenclatura dos méotodos,
quanto mais significativa, melhor. Podem perceber que só pelo nome dos
métodos vocês já conseguem identificar o que eles fazem.
Se você rodar este código usando com $mvn clean install, vai obter um resultado semelhante a este abaixo:
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building testng-spring-mockito-maven
[INFO]
[INFO] Id: com.blogspot.diegopacheco.sandbox.java:testng-spring-mockito-maven:jar:1.0
[INFO] task-segment: [clean, install]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory D:\Diego\Java\bin\workspaces-eclipse\eclipse_workspace\testng-spring-mockito-maven\target
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 8 source files to D:\Diego\Java\bin\workspaces-eclipse\eclipse_workspace\testng-spring-mockito-maven\target\classes
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Compiling 1 source file to D:\Diego\Java\bin\workspaces-eclipse\eclipse_workspace\testng-spring-mockito-maven\target\test-classes
[INFO] [surefire:test]
[INFO] Surefire report directory: D:\Diego\Java\bin\workspaces-eclipse\eclipse_workspace\testng-spring-mockito-maven\target\surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestSuite
31/07/2009 00:14:25 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-test-beans.xml]
31/07/2009 00:14:26 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericApplicationContext@8916a2: display name [org.springframework.context.support.GenericApplicationContext@8916a2]; startup date [Fri Jul 31 00:14:26 BRT 2009]; root of context hierarchy
31/07/2009 00:14:26 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
INFO: Bean factory for application context [org.springframework.context.support.GenericApplicationContext@8916a2]: org.springframework.beans.factory.support.DefaultListableBeanFactory@39443f
31/07/2009 00:14:26 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@39443f: defining beans [org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.config.internalBeanConfigurerAspect,vendaServiceImpl,org.springframework.aop.config.internalAutoProxyCreator]; root of factory hierarchy
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.323 sec
Results :
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
31/07/2009 00:14:26 org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.GenericApplicationContext@8916a2: display name [org.springframework.context.support.GenericApplicationContext@8916a2]; startup date [Fri Jul 31 00:14:26 BRT 2009]; root of context hierarchy
31/07/2009 00:14:26 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@39443f: defining beans [org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.config.internalBeanConfigurerAspect,vendaServiceImpl,org.springframework.aop.config.internalAutoProxyCreator]; root of factory hierarchy
[INFO] [jar:jar]
[INFO] Building jar: D:\Diego\Java\bin\workspaces-eclipse\eclipse_workspace\testng-spring-mockito-maven\target\testng-spring-mockito-maven-1.0.jar
[INFO] [source:jar]
[INFO] Building jar: D:\Diego\Java\bin\workspaces-eclipse\eclipse_workspace\testng-spring-mockito-maven\target\testng-spring-mockito-maven-1.0-sources.jar
[INFO] [install:install]
[INFO] Installing D:\Diego\Java\bin\workspaces-eclipse\eclipse_workspace\testng-spring-mockito-maven\target\testng-spring-mockito-maven-1.0.jar to C:\Users\Diego Pacheco\.m2\repository\com\blogspot\diegopacheco\sandbox\java\testng-spring-mockito-maven\1.0\testng-spring-mockito-maven-1.0.jar
[INFO] Installing D:\Diego\Java\bin\workspaces-eclipse\eclipse_workspace\testng-spring-mockito-maven\target\testng-spring-mockito-maven-1.0-sources.jar to C:\Users\Diego Pacheco\.m2\repository\com\blogspot\diegopacheco\sandbox\java\testng-spring-mockito-maven\1.0\testng-spring-mockito-maven-1.0-sources.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6 seconds
[INFO] Finished at: Fri Jul 31 00:14:27 BRT 2009
[INFO] Final Memory: 5M/21M
[INFO] ------------------------------------------------------------------------
Agora temos o nosso primeiro teste usando
Spring, TestNG, conceitos e práticas de testes unitários e maven. No
próximo artigo vou mostrar mais testes com o TestNG e vou apresentar o
Mockito. O artigo seguinte será focado somente nos testes, então, não
percam.
Abraços e até a próxima.