Business Delegate e Service Locator

37 respostas
Luiz_Henrique_Coura

Criei uma interface chamada HandleDB que contém métodos para manipulação no banco de dados (insert, remove, update, list).
Tenho 4 classes: (Todas implementam HandleDB)
-ModelAdmin
-VariableAdmin
-StationAdmin
-StateAdmin
Essa é a camada de negócio.

Minha dúvida é a seguinte:

Quero utilizar Business Delegate e Service Locator para me conectar a camada de negócio, mas eu tenho dúvida qt à implementação desses patterns.

Eu poderia fazer assim?

public class MeuBusinessDelegate {
    public void insert(Object obj) {
        MeuServiceLocator sl = new MeuServiceLocator();
        sl.insert(Object obj);
    }

    public void remove(Object obj) {}
    public void update(Object obj) {}
    public List list(Object obj) {}
}
public class MeuServiceLocator {
    public void insert(Object obj){
        HandleDB handleDB = null;

        if(obj instanceof ModelBean) handleDB = new ModelAdmin();
        if(obj instanceof VariableBean) handleDB = new VariableAdmin();
        if(obj instanceof StationBean) handleDB = new StationAdmin();
        if(obj instanceof StateBean) handleDB = new StateAdmin();

        if(handleDB != null) handleDB.insert(obj);
    }
.
.
.
}

Enfim, utilizo o Service Locator para ocultar os detalhes da implementação por trás do código de pesquisa de serviço de negócios.

É isso mesmo? Eu poderia fazer assim? Isso está certo?

37 Respostas

jgbt

vc ta decidindo qual objeto retornar no service locator.
acho que ta misturando as coisas.
p/ mim o service locator deve retornar um objeto, não precisa conhece-lo.
acho que vc poderia mudar esse trecho de codigo p/ uma factory.ela sim tomaria a decisão de qual objeto retornar.

[]'s

Luiz_Henrique_Coura

Realmente, o q eu fiz se parece mais com uma factory!

O service locator se encaixa mais na utilização de EJB’s, onde eu pegaria o serviço e apresentaria para o business delegate?

Não implementei minha camada de negócios com EJB’s. O service locator se aplica somente a esse tipo de implementação?

jgbt

acho que vc pode ter uma classe tipo service locator, que retornace um new instance de um object qualquer, e na classe que chma vc faz o cast p/ o sua classe.
e uma factory que buscasse o tipo de obj.

[]'s

Luiz_Henrique_Coura

Fiz assim:

Meu DB:

public class BusinessDelegate {
    public void insert(Object obj) {
        HandleDB handleDB = HandleDBFactory.getHandleDB(obj);
        handleDB.insert(Object obj);
    }
}

Minha Factory:

public class HandleDBFactory {
    public synchronized static HandleDB getHandleDB( Object obj ) {
        if( obj == null ) return null;
        else if( obj instanceof CountryBean ) return new CountryAdmin();
        else if( obj instanceof StateBean ) return new StateAdmin();
        else if( obj instanceof StationBean ) return new StationAdmin();
        else if( obj instanceof ModelBean ) return new ModelAdmin();
        else if( obj instanceof VariableBean ) return new VariableAdmin();
        else return null;
    }
}

Não consegui imaginar como eu usaria um service locator nesse caso. Tem como? Como ficaria?

pcalcado

Use ServiceLocator basicamente para JNDI e outros esquemas 'passa-string-recebe-objeto".

Por que seu método é sincronizado?

Considere utilizar um framework de IoC como o Spring e ser mais feliz :slight_smile:

[]s

louds

O Service Locator é uma forma de Factory.

Fora isso você está misturando a camada de persistencia com a de negocios.

Luiz_Henrique_Coura

A respeito do synchonized é uma dúvida q eu tenho faz tempo.

Pode acontecer de, por ser um método estático, meu objeto ser trocado por uma outra thread executando ao mesmo tempo esse método?

Vamos supor q um usuário entrou no sistema junto com outro usuário. Os dois pedem uma requisição e ao mesmo tempo eles entram nesse método. Não pode acontecer de retornar um valor errado?

Pensei em colocar synchronized, para q esse método seja executado separadamente, sem inteferir com outras threads.

pcalcado

isso deve te ajudar a entender melhor :wink:

Basicamente o método vai executar várias vezes, mas cada vez é única e não interfere com as outras. O que você pode ter problema é se os métodos acessarem um recurso em comum, como um atributo (estático, no caso), aí eles pdoem alterar o valor ao mesmo tempo e essas coisas.

O objeto que vc retorna numa thread é dela e ng tasca :slight_smile:

[]s

Luiz_Henrique_Coura

hmmm! entendi! :smiley:
Valew!

louds:
O Service Locator é uma forma de Factory.

Fora isso você está misturando a camada de persistencia com a de negocios.

Uma Framework de persistência já implementa a separação da camada de negócio?
É q estou estudando Struts e pretendo começar a estudar algum Framework para trabalhar com persistência.

O q vc sugere?

pcalcado

eu sugiro :slight_smile:

MVC: WebWork ou Spring IoC
Persistência: Hibernate ou JDBC+DAO, se o sistema for simples
Gerência da procaria toda: Spring

Tudo depende dos seus requisitos na verdade, e do tempo hábil.

(eu não usaria Struts, foi lançada a pouco a campanha SALVEM AS FOCAS)

Luiz_Henrique_Coura

Campanha Salvem as Focas?

Não entendi!

Qual o problema de utilizar Struts?

:?: :?:

smota

Luiz Henrique Coura:
Campanha Salvem as Focas?
Não entendi!
Qual o problema de utilizar Struts?
:?: :?:

Aqui ele teve essa inspiração …

PS: Pessoaaal, achei esse post ai de cima no Google, finalmente o forum do guj está indexado que é uma beleza!!!

PS2: 99,767

Diogenes

Tâmo quase lá! :wink:

Ô Shoes, bem q tuh podia colocar uma foquinha nesse avatar seu neh?!
O Greenpeace ia adorar! :lol:

cv1

Ja que usaram meu nome (iniciais?) em vao, eu vou dar pitaco tambem.

Nao use ServiceLocators nem Factories. Ja tiveram todo o trabalho de fazer uma PUTA factory generica, que eh o Spring. Se voce tiver sem saco de usar o Spring, ou ficar com nojinho do XML, voce pode usar o PicoContainer. Mas nao faca ServiceLocator ou Factory na mao, a menos que vc queira consertar depois. Pq ninguem faz isso direito :smiley:

_fs

E sobre Struts, não conheço um utilizador de Struts que, após brincar umas horinhas com o WebWork não se converteu hehe :smiley:

Aposto que você deu um suspiro bem desgostoso depois de ver o tamanho da lista de frameworks que o povo sugeriu né? :smiley:

ps.: cv, seu comédia :mrgreen:

kuchma

E por favor - se resolver fazer, conserte mesmo. Nao va deixar como legado para outros desenvolvedores inocentes.

Sobre GUJ+Google: sim, reparei que ta rolando mesmo. Inclusive algumas pesquisas que faco retornam o GUJ na primeira pagina… ontem mesmo pesquisei por “Eclipse 3.1M4 Lomboz” e adivinhem qual foi o primeirao da lista? (e eu nem pedi pra pesquisar apenas em portugues)

Marcio Kuchma

caiofilipini

Shoes, porque não usar Hibernate em sistemas simples? Não vejo problema nenhum… Alguns podem dizer que é muito esforço pra pouco ganho, ou algo assim, mas só de não ter que botar a mão em SQL e iterar sobre ResultSets pra montar Collections, já vale a pena, na minha opinião. :wink:

Mas o DAO é válido nos dois casos. Exemplo foi um sistema simples que eu fiz pra um órgão interno da facul… Nunca tinha usado Hibernate, e comecei usando JDBC + DAO + WebWork. Depois resolvi usar o Hibernate, e sabe o que eu precisei mudar? O components.xml do XWork, pra instanciar meus HibernateDAOs ao invés dos JDBC… :smiley:

[]'s

pcalcado

caiofilipini:

Shoes, porque não usar Hibernate em sistemas simples? Não vejo problema nenhum… Alguns podem dizer que é muito esforço pra pouco ganho, ou algo assim, mas só de não ter que botar a mão em SQL e iterar sobre ResultSets pra montar Collections, já vale a pena, na minha opinião. :wink:

Tudo dependo do que é simples para você ou para mim. Se eu precisar fazer apenas uma consulta a um SGBD no sistema todo, não vou usar hibernate :wink:

Não dá pra usar tamanho único, não dá para catalogar baseado em conceitos como simplicidade… enfim, só tem uma cosia que te diz: experiência e muitas horas perdidas consertando alguma merda.

cv, autoriza o Lipe a fazer um logo ‘salvem as focas’ ae, tipo o que se fez no CJ’04 8) pra colocar em blog, assinatura, camiseta, camisinha, cartaz em ônibus, envelopar as barcas da baia de guanabara…
(sim, eu gosto de dar trabalho pros outros)

rodrigousp

:?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?:
:shock: :shock: :shock: :shock: :shock: :shock: :shock: :shock:

Por que usar struts: ibm, bea, sun, oracle, ford, toyota, gm, deustchebank, bank boston, oesp, folha, ig …
Não sei, trabalhei em poucos lugares. Não deve servir de opinião o fato de 100% dos lugares utilizarem struts, e em geral “isto” ser um requisito do cliente.

Territorial Pissings

Assim segue… Se é verdade que o “profeta falou”, pobres foquinhas…

pcalcado

Rodrigo,

Se você quer usar Struts, ótimo, use.

Se você vai usar Struts porque é ‘padrãod e mercado’, se for esperto vai aprender a tecnologia, mas não se agarrar à ela como o cálice de salvação.

Se for procurar a melhor solução, vai saber que o Struts não é.

Deixa eu te contar uma historinha.

Se você olhar alguns posts aqui de alguns anos atrás, vai ver que muita gente (inclusive eu) recomendava o Struts. O que as pessoas diziam?

As pessoas que realmente vivem tecnologia, que gostam e procuram as melhores soluções já estavbam de saco cheio de saber que o modelo Servlet+JSP estava obsoleto para aplicações que exigem um pouco mais de elaboração.

De tanto encher o saco, as pessoas começaram a usar e gostar do Struts. Começou a se tornar o ‘padrão da indústria’. Emrpesas como as citadas acima começaram a usar. Pena que isso acotneceu há poucos meses, e agora o Struts parou no tempo. A API nunca foi grande coisa, mas ela simplesmente está fora da realidade atual, do que se procura no desenvolvimento de sistemas.

Você ouve a galera aqui e em tantos outros lugares falando em IoC, containers leves, fora-EJB, fora-Struts… amanhã isso tudo vai ser padrão de mercado, porque quem procura saber o que fala acaba ditando a moda.

Eu posso te citar uma lsita ainda maior de emrpesas que usam ASP ou CGI… você iria usar isso por causa desta lista?

Ah, de onde você tirou esse seu 100%? Me manda um link apra essa informação, por favor.

Raramente eu vejo um clietne requisitar Struts, C/C++, java… na verdade eu muito mal vejo cliente requisitando computadores. Eu acho que eles já tem muita obrigação requisitando processos e domínios de negócio para se preocupar com isso, que não vale nada para eles.

rodrigousp

Pcalcado,

Muito legal sua resposta.

Antes de começar, o 100% foram dos que eu conheci. Nem de longe somam uma amostra relevante da população para se basear qualquer afirmação científica. É, tipo assim… “eu acho”.

Agora respondendo:

Antes mesmo de começar a usar o Struts eu já sabia que existia soluções melhores. No próprio livro do Programming Jakarta Struts, fala sobre várias alternativas… Então nesta ocasião eu escolhi o Struts. Por que: documentação eh muito boa (I love the Apache Project) e já havia uma tendência do mercado graças ao suporte oferecido pela IBM.

Alias, permita me um comentario pessoal, mas o suporte da IBM muda a forma com que o mundo enxerga uma tecnologia. Foi assim com os PCs, com o java (j2ee), etc.

De fato, existem tecnologias maneirissimas por ai. Ontem mesmo estava falando com um amigo meu que desenvolve em Oracle sobre o prevayler, e a ideia de manter objetos em memoria. E eu sei que o banco de dados como a gente conhece ja eh uma coisa ultrapassada, mesmo nao existindo algo que o possa substituir assim, sem maiores retoques. E este meu amigo concorda com isso.

Dai a abandonar o banco de dados porque existem ideias melhores, nao rola! Claro que empresas pessoais que nao tem requisitos de nenhuma diretoria iberoamericana nem diretriz mundial, e/ou coisas do genero, podem arriscar caminhos maisalternativos(modernos).

Para ter-se uma ideia do que eh “modernidade”: eh sempre um sufoco convercer as pessoas a utilizarem as surrogate keys. O mundo acredita, pasme!, que isto eh " totalmente fora da realidade".

Nao meu amigo… sem o suporte de pelo menos alguma empresa grande eh muito dificil escolher por alguma tecnologia e o que eu vejo neste sentido eh que os grandes vendors de servidores de aplicacao estao no auge do suporte ao Struts (IBM Websphere, Bea Weblogic Workshop, Oracle Developer, Exadel) e migrando para um suporte ao JSF.

(acho que ja escrevi metade do que queria escrever… mas vou dar outra pausa)
(versão 0.2 _ :smiley: )

Focao

Olá galera ! gostei da foquinha ! Queria mas detalhe de como surgiu essa grande e ilária idéia.

Opinião sobre o Struts…

a anos se vc fosse em uma entrevista e falasse que não conhecia VB (lembra Microsoft Visual Basic tinha o 2, 3, 4, service pack n…) tava fora.

e hj é a mesmo coisa com o struts…

se vc usa .do coitado tá no passado

se vc usa .faces tá ficando ninja e olhando pro futuro.

opnião própria sem preconceito pois struts é como mulher feia e pantufa a gente usa em casa mas tem vergonha de sair na rua kkkkkkkkk

Thiago_Senna

Pelo que li nas discussões, acho que esse aqui é o link de onde começou a história maldosa no qual incluiram as focas!

http://www.guj.com.br/posts/list/18258.java

Se usarmos spring ou webwork Deus salva as foquinhas???

rsrs…

J

Até alguns dias eu também era adepto dos odiadores do struts, pois o achava muito fraco na camada de view.
(percebo que muita gente não dá importancia, mas o que o usuário vê é a view)
Mas conheci a extensão struts layout.
Parece ser excelente. Não usei mais pelo que dá para perceber aumenta muito a produtividade forcenedo vários componentes.
Eu concordo que o struts complica o simples.

Mas o tópico tomou outro rumo…

Focao

Legal jprogramer,
agora entendi

é que nunca tinha usado struts dessa maneira achei

achei estranha a arquitetura do Business Delegate

um uso simples que adoto é esse

import java.util.ArrayList;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import java.io.*;

public class ImprimeVendasAction extends Action {
	/* (non-Javadoc)
	 * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	public ActionForward execute(
		ActionMapping mapping,
		ActionForm form,
		HttpServletRequest request,
		HttpServletResponse response) {
		// FAZER Auto-generated method stub
		this.salvaVendas(request);

		return mapping.findForward("view");
	}
	public void salvaVendas(HttpServletRequest request ) {
		ArrayList list =
			(ArrayList) request.getSession().getAttribute("listaVendas");
		ListaVendas obj;
	//implement interator

	}

}
cv1

jprogrammer:
Mas conheci a extensão struts layout.
Parece ser excelente. Não usei mais pelo que dá para perceber aumenta muito a produtividade forcenedo vários componentes.
Eu concordo que o struts complica o simples.

Pra isso tambem ja tem resposta, o Sitemesh :slight_smile:

J

Dá uma olhada nisso.
http://struts.application-servers.com/doc/index.html

Eu achei bem bacana.
Agora o que o seu código tem a ver com Business Delegate ?

Mas Business Delegate serve para instanciar as classes de dominio e regras de negócio.

No meu modo de ver Business Delegate:

class Funcionarios

{

public void inserir(Funcionario func)

{

// aqui regras de negócio e validações

FuncionarioDAO.inserir(func);

}

}

class BusinessDelegate

{

public Funcionarios getFuncionarios()

{

// se estiver instancia local

return new Funcionarios();
// senão chama Service Locator para criar objeto de EJB, Web Service, etc

}
}

BusinessDelegate businessDelegate = new BusinessDelegate ()

Funcionarios funcionarios = businessDelegate.getFuncionarios();

Funcionario func = new Funcionario();

func.setCodigo(1);

func.setNome(Maria)


funcionarios.inserir(func);

cv1

Focao: desse jeito, vc esta acoplando a Action e a especificacao de Servlets (ao usar HttpServletRequest etc). O que voce faria caso precisasse rodar isso sem subir as classes num web container, por exemplo, pra testes unitarios?

F

É por essa e outras que existe a acampanha.

import java.util.ArrayList;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import java.io.*;

public class ImprimeVendasAction extends Action {
	/* (non-Javadoc)
	 * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	public ActionForward execute(
		ActionMapping mapping,
		ActionForm form,
		HttpServletRequest request,
		HttpServletResponse response) {
		// FAZER Auto-generated method stub
		this.salvaVendas(request);

		return mapping.findForward("view");
	}
	public void salvaVendas(HttpServletRequest request ) {
		ArrayList list =
			(ArrayList) request.getSession().getAttribute("listaVendas");
		ListaVendas obj;
	//implement interator

	}

}
import java.util.ArrayList;
....

public class ImprimeVendasAction extends ActionSuport {

    private List listVendas = null;

    public void salvaVendas() {
      //Delega o acao de salvar a lista de vendas.
    }
    public void setListVendas(List listVendas) {
      this.listVendas = listVendas;
    }
}

Que diferença.

:mrgreen:

Focao

putz cv ! O ruim o o bom de usar uma ide poderosa é isso

no JDeveloper 10g

vc falow de como subir as classes num web container, por exemplo, pra testes unitarios.

isso é trivial e transparente. por debug ou por JUnit

Apesar que eu não acho legal o delagate om problema é Abstrair os clientes da complexidade de comunicação remota com componentes de serviços de negócio (Business services).

Mas valeu gostei muito da galera daqui e dos foruns que rola

mas ainda teimo que seria mais elegante assim

ComponeteNegocioBusinessDelegate.java
...
import br.ufrj.nce.tees4.ComponenteNegocio;
import br.ufrj.nce.tees4.ComponenteNegocioHome;
import br.ufrj.nce.tees4.servicelocator.ServiceLocator;
public class ComponeteNegocioBusinessDelegate {
private static final String JNDI_NAME_COMPONENTE_NEGOCIO = "ejb/br/ufrj/nce/tees4/ComponenteNegocioHome";
public String metodoNumeroUm() throws BusinessDelegateException, ExcecaoNegocio1
	{
	ComponenteNegocio bean = this.getBean();
...	return bean.metodoNumeroUm(); ...	}
private ComponenteNegocio getBean() throws BusinessDelegateException
	{
	ComponenteNegocio bean; ...
	ServiceLocator sl = new ServiceLocator();
	ComponenteNegocioHome home = (ComponenteNegocioHome)sl.getRemoteHome(JNDI_NAME_COMPONENTE_NEGOCIO,ComponenteNegocioHome.class);
	bean = home.create(); ... 	return bean; 	} }

aí sim estariamos reduzindo o acoplamento entre os clientes da camada de apresentação e os serviços de negócios
ocultando detalhes de implementação dos serviços de negócios, como detalhes de pesquisa e acesso da arquitetura EJB

e olha isso que chique nu úrtimo como diz uma camarada mineirinho

ComponenteNegocioBean.java
...
public class ComponenteNegocioBean implements javax.ejb.SessionBean {
...	
	public String metodoNumeroUm() throws ExcecaoNegocio1
	{
		return "Método Número 1 !!";
	}
	
	public String metodoNumeroDois() throws ExcecaoNegocio2
	{
		return "Método Número 2 !!";
	}

}

abrçs a todos

Focao

Putz nada seria válido sem o

ServiceLocator.java

...

public class ServiceLocator {
...
public ServiceLocator() throws ServiceLocatorException {
	try {
		ic = new InitialContext();
...
	}
public EJBHome getRemoteHome(String jndiHomeName, Class className)
	throws ServiceLocatorException {
	EJBHome home = null;
	try {
		Object objref = ic.lookup(jndiHomeName);
		Object obj = PortableRemoteObject.narrow(objref, className);
		home = (EJBHome) obj;
		} catch (NamingException ne) {
		throw new ServiceLocatorException(ne);
		}
		return home;
	} ... }

até :slight_smile:

cv1

Focão:
putz cv ! O ruim o o bom de usar uma ide poderosa é isso

no JDeveloper 10g

vc falow de como subir as classes num web container, por exemplo, pra testes unitarios.

isso é trivial e transparente. por debug ou por JUnit

A pergunta foi bem simples: como voce roda um teste unitario em uma Action do Struts sem subir um container e sem fazer todo tipo de malabarismo com mocks, e a resposta tambem eh simples: nao da, e eh por essas e outras que pessoas que usam Struts de proposito (ou seja, aqueles que nao sao forcados a usa-lo por PHBs) acabam desenvolvendo habitos pouco ortodoxos, como andar pelo escritorio batendo o proprio saco nas quinas dos cubiculos.

Nao venha me dizer que usar JDeveloper ajuda nessa situacao, pq merda perfumada continua sendo… merda.

cv1

O que vc prefere que eu use pra te bater por isso, um PicoContainer, um Spring ou um Hivemind? :mrgreen:

Pessoas, encham o Focao de links sobre IoC e DI, ele precisa ser catequizado :stuck_out_tongue:

_fs

hehe Focão, dá um procurada por Inversion of Control e Proxy Pattern.

Aqui alguns links:


O cv é meio metidinho mesmo ( :XD: ), mas não me lembro uma vez que me arrependi de seguir alguma sugestão dele, assim como de alguns outros aqui no fórum :thumbup:

F

Pra teste unitario nao ajuda nao. Tambem uso ele e nesse ponto nao faz muita diferenca do restante de IDE.
Por sinal pra JUnit nao tem como o Eclipse, mas tambem ja era de se esperar por isso neh. :mrgreen:

]['s

rodrigousp

cv:

A pergunta foi bem simples: como voce roda um teste unitario em uma Action do Struts sem subir um container e sem fazer todo tipo de malabarismo com mocks, e a resposta tambem eh simples: nao da, e eh por essas e outras que pessoas que usam Struts de proposito (ou seja, aqueles que nao sao forcados a usa-lo por PHBs) acabam desenvolvendo habitos pouco ortodoxos, como andar pelo escritorio batendo o proprio saco nas quinas dos cubiculos.

Nao venha me dizer que usar JDeveloper ajuda nessa situacao, pq merda perfumada continua sendo… merda.

E se eu dizer que palavras de baixos calão não ajudam a convencer ninguém !? Para CV! você sabe como argumentar… Se não tá afim de usar bons argumentos não precisa nem postar nada (é pelo menos mais amistoso, mais agradável ver um forum assim).

NOTA IMPORTANTE: NÃO DEFENDO O STRUTS…
ASSIM MESMO SE QUISER FAZER UM TESTE DE UNIDADE…
NÃO PRECISA DAS CENAS DE MASOQUISMO, SÓ UM FRAMEWORK (StrutsTestCase).

// Pre-condincao
StrutsTestFrame myStruts = new StrutsTestFrame("struts-config.xml");
request = myStruts.getRequest();
response = myStruts.getResponse();
request.set( qualquer coisa);
MyActionForm form = new MyActionForm();
form.set(qualquer coisa);
MyAction action = new MyAction();

// invoque o test
ActionForward find = action.execute(request, response, form, mapping); 

...
cv1

Bom, o fato de vc precisar de um framework a mais pra fazer testes unitarios - que nao deveriam depender de nada, especialmente de um framework - ja diz bastante coisa, nao? :wink:

Compare isso com o teste unitario de uma Action do WebWork, onde voce so precisa do JUnit ou do TestNG :slight_smile:

Criado 14 de janeiro de 2005
Ultima resposta 11 de mar. de 2005
Respostas 37
Participantes 15