https://dosideas.com/wiki/api.php?action=feedcontributions&user=Zabalet&feedformat=atomDos Ideas. - Contribuciones del usuario [es]2024-03-28T16:23:09ZContribuciones del usuarioMediaWiki 1.28.2https://dosideas.com/wiki/index.php?title=Captura_De_Parametros&diff=1145Captura De Parametros2008-10-10T17:55:53Z<p>Zabalet: /* Captura de parámetro con Mockito */</p>
<hr />
<div>Hay situaciones en las que el estamos realizando un testeo con un [[Mock Object]] y queremos capturar un parámetro que recibe el mismo.<br />
<br />
Esta situación suele producirse cuando hay un objeto que se crea dentro de los objetos que estamos probando y llega como parámetro a algún [[Mock Object]]. Hay unas cuantas condiciones que podemos pedir a EasyMock y Mockito que validen como parámetro esperado como por ejemplo igualdad, expresiones regulares, no nulo, nulo, algunas comprobaciones con Strings y primitivos, etc. Pero incluso a veces esto no alcanza. El objeto fue creado dentro de otro objeto, es decir que no podemos ni inyectarlo desde fuera ni conseguirlo por medios naturales y queremos inspeccionar sus atributos y realizar una serie de asserts. Es ahí cuando conseguir una referencia al mismo nos resulta indispensable.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorMasPeligroso();<br />
}<br />
</code><br />
<br />
... la siguiente interfaz de DAO<br />
<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorPorFiltro(Filtro filtro);<br />
}<br />
</code><br />
<br />
... y el siguiente filtro<br />
<br />
<code java><br />
public class Filtro {<br />
<br />
private Fuerza fuerza;<br />
private Velocidad velocidad;<br />
private Destreza destreza;<br />
<br />
// sus metodos accesores<br />
}<br />
</code><br />
<br />
Dentro de la implementación de la clase PlanInvasionBo se crea una instancia de Filtro que se utiliza para comunicarse con el DAO pero no es externalizada en ningún momento (salvo como parámetro en la llamada al método del DAO) ni existe la posiblidad de inyectarla desde fuera.<br />
<br />
<code java><br />
public class PlanInvasorBoImpl implements PlanInvasor {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
// otros atributos<br />
<br />
public Invasor findInvasorMasPeligroso() {<br />
<br />
// Realiza ciertos guarismos internos <br />
// para determinar la Fuerza, Velocidad y Destreza<br />
Fuerza fuerza = calcularFuerza();<br />
Velocidad velocidad = calcularVelocidad();<br />
Destreza destreza = calcularDestreza();<br />
<br />
// Utiliza los valores determinados para construir un Filtro<br />
Filtro filtro = new Filtro(fuerza, velocidad, destreza);<br />
<br />
// Llama al DAO con el filtro construido internamente<br />
return planInvasionDao.findInvasorPorFiltro(filtro);<br />
}<br />
// otros metodos<br />
<br />
}<br />
</code><br />
<br />
===El objetivo===<br />
<br />
El objetivo que nos planteamos es poder inspeccionar en un test que los valores del objeto Velocidad estén dentro de ciertos límites.<br />
<br />
===El problema===<br />
<br />
El problema que tenemos es que el objeto Velocidad se crea a partir de unos métodos privados de PlanInvasionBo y está dentro de otro objeto que se crea también dentro de PlanInvasionBo al que tampoco tenemos acceso.<br />
La única comunicación de este objeto con el exterior es en forma de parámetro a través de la llamada al método del DAO.<br />
<br />
=Una posible solución=<br />
<br />
Una posible solución a nuestro objetivo es capturar el parámetro Filtro que recibe el método del DAO que en el caso del test será un [[Mock Object]].<br />
<br />
==Captura de parámetro con EasyMock==<br />
<br />
La forma de capturar un parámetro con [[EasyMock]] es creando un objeto Capture parametrizado con la clase que va a capturar.<br />
Luego, en la maquetación del método, se utiliza el método estático EasyMock.capture que recibe al capturador.<br />
Luego de ejercitar el método podemos pedirle el valor capturado al capturador.<br />
<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao daoMock;<br />
<br />
protected void setUp() throws Exception {<br />
daoMock = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(daoMock);<br />
}<br />
<br />
public void testFindInvasorMasPeligroso() {<br />
<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
// Crear un Capture para utilizar en la maquetacion del metodo<br />
Capture<Filtro> caturaFiltro = new Capture<Filtro>();<br />
<br />
expect(mockDao.findInvasorPorFilro(capture(capturaFiltro)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
// los assert tipicos<br />
<br />
// Conseguir la referencia al filtro que llego como parametro<br />
// al metodo del daoMock<br />
Filtro filtro = capturaFiltro.getValue();<br />
<br />
assertNotNull(filtro);<br />
assertTrue(filtro.getVelocidad() < VELOCIDAD_MAXIMA);<br />
// El resto de los asserts necesarios sobre el filtro<br />
<br />
}<br />
}<br />
</code><br />
<br />
==Captura de parámetro con Mockito==<br />
<br />
(Agregar descripcion y codigo de Mockito)<br />
<br />
===Extensión del Matcher de Mockito===<br />
<br />
(Agregar descripcion y codigo del Matcher capturador)<br />
<br />
=Ver también=<br />
* [[Easy Mock]]<br />
* [[Mockito]]<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Captura_De_Parametros&diff=1144Captura De Parametros2008-10-10T17:55:28Z<p>Zabalet: /* Captura de parámetro con EasyMock */</p>
<hr />
<div>Hay situaciones en las que el estamos realizando un testeo con un [[Mock Object]] y queremos capturar un parámetro que recibe el mismo.<br />
<br />
Esta situación suele producirse cuando hay un objeto que se crea dentro de los objetos que estamos probando y llega como parámetro a algún [[Mock Object]]. Hay unas cuantas condiciones que podemos pedir a EasyMock y Mockito que validen como parámetro esperado como por ejemplo igualdad, expresiones regulares, no nulo, nulo, algunas comprobaciones con Strings y primitivos, etc. Pero incluso a veces esto no alcanza. El objeto fue creado dentro de otro objeto, es decir que no podemos ni inyectarlo desde fuera ni conseguirlo por medios naturales y queremos inspeccionar sus atributos y realizar una serie de asserts. Es ahí cuando conseguir una referencia al mismo nos resulta indispensable.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorMasPeligroso();<br />
}<br />
</code><br />
<br />
... la siguiente interfaz de DAO<br />
<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorPorFiltro(Filtro filtro);<br />
}<br />
</code><br />
<br />
... y el siguiente filtro<br />
<br />
<code java><br />
public class Filtro {<br />
<br />
private Fuerza fuerza;<br />
private Velocidad velocidad;<br />
private Destreza destreza;<br />
<br />
// sus metodos accesores<br />
}<br />
</code><br />
<br />
Dentro de la implementación de la clase PlanInvasionBo se crea una instancia de Filtro que se utiliza para comunicarse con el DAO pero no es externalizada en ningún momento (salvo como parámetro en la llamada al método del DAO) ni existe la posiblidad de inyectarla desde fuera.<br />
<br />
<code java><br />
public class PlanInvasorBoImpl implements PlanInvasor {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
// otros atributos<br />
<br />
public Invasor findInvasorMasPeligroso() {<br />
<br />
// Realiza ciertos guarismos internos <br />
// para determinar la Fuerza, Velocidad y Destreza<br />
Fuerza fuerza = calcularFuerza();<br />
Velocidad velocidad = calcularVelocidad();<br />
Destreza destreza = calcularDestreza();<br />
<br />
// Utiliza los valores determinados para construir un Filtro<br />
Filtro filtro = new Filtro(fuerza, velocidad, destreza);<br />
<br />
// Llama al DAO con el filtro construido internamente<br />
return planInvasionDao.findInvasorPorFiltro(filtro);<br />
}<br />
// otros metodos<br />
<br />
}<br />
</code><br />
<br />
===El objetivo===<br />
<br />
El objetivo que nos planteamos es poder inspeccionar en un test que los valores del objeto Velocidad estén dentro de ciertos límites.<br />
<br />
===El problema===<br />
<br />
El problema que tenemos es que el objeto Velocidad se crea a partir de unos métodos privados de PlanInvasionBo y está dentro de otro objeto que se crea también dentro de PlanInvasionBo al que tampoco tenemos acceso.<br />
La única comunicación de este objeto con el exterior es en forma de parámetro a través de la llamada al método del DAO.<br />
<br />
=Una posible solución=<br />
<br />
Una posible solución a nuestro objetivo es capturar el parámetro Filtro que recibe el método del DAO que en el caso del test será un [[Mock Object]].<br />
<br />
==Captura de parámetro con EasyMock==<br />
<br />
La forma de capturar un parámetro con [[EasyMock]] es creando un objeto Capture parametrizado con la clase que va a capturar.<br />
Luego, en la maquetación del método, se utiliza el método estático EasyMock.capture que recibe al capturador.<br />
Luego de ejercitar el método podemos pedirle el valor capturado al capturador.<br />
<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao daoMock;<br />
<br />
protected void setUp() throws Exception {<br />
daoMock = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(daoMock);<br />
}<br />
<br />
public void testFindInvasorMasPeligroso() {<br />
<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
// Crear un Capture para utilizar en la maquetacion del metodo<br />
Capture<Filtro> caturaFiltro = new Capture<Filtro>();<br />
<br />
expect(mockDao.findInvasorPorFilro(capture(capturaFiltro)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
// los assert tipicos<br />
<br />
// Conseguir la referencia al filtro que llego como parametro<br />
// al metodo del daoMock<br />
Filtro filtro = capturaFiltro.getValue();<br />
<br />
assertNotNull(filtro);<br />
assertTrue(filtro.getVelocidad() < VELOCIDAD_MAXIMA);<br />
// El resto de los asserts necesarios sobre el filtro<br />
<br />
}<br />
}<br />
</code><br />
<br />
=Captura de parámetro con Mockito=<br />
<br />
(Agregar descripcion y codigo de Mockito)<br />
<br />
==Extensión del Matcher de Mockito==<br />
<br />
(Agregar descripcion y codigo del Matcher capturador)<br />
<br />
=Ver también=<br />
* [[Easy Mock]]<br />
* [[Mockito]]<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Captura_De_Parametros&diff=1143Captura De Parametros2008-10-10T17:55:14Z<p>Zabalet: /* Una posible solución */</p>
<hr />
<div>Hay situaciones en las que el estamos realizando un testeo con un [[Mock Object]] y queremos capturar un parámetro que recibe el mismo.<br />
<br />
Esta situación suele producirse cuando hay un objeto que se crea dentro de los objetos que estamos probando y llega como parámetro a algún [[Mock Object]]. Hay unas cuantas condiciones que podemos pedir a EasyMock y Mockito que validen como parámetro esperado como por ejemplo igualdad, expresiones regulares, no nulo, nulo, algunas comprobaciones con Strings y primitivos, etc. Pero incluso a veces esto no alcanza. El objeto fue creado dentro de otro objeto, es decir que no podemos ni inyectarlo desde fuera ni conseguirlo por medios naturales y queremos inspeccionar sus atributos y realizar una serie de asserts. Es ahí cuando conseguir una referencia al mismo nos resulta indispensable.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorMasPeligroso();<br />
}<br />
</code><br />
<br />
... la siguiente interfaz de DAO<br />
<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorPorFiltro(Filtro filtro);<br />
}<br />
</code><br />
<br />
... y el siguiente filtro<br />
<br />
<code java><br />
public class Filtro {<br />
<br />
private Fuerza fuerza;<br />
private Velocidad velocidad;<br />
private Destreza destreza;<br />
<br />
// sus metodos accesores<br />
}<br />
</code><br />
<br />
Dentro de la implementación de la clase PlanInvasionBo se crea una instancia de Filtro que se utiliza para comunicarse con el DAO pero no es externalizada en ningún momento (salvo como parámetro en la llamada al método del DAO) ni existe la posiblidad de inyectarla desde fuera.<br />
<br />
<code java><br />
public class PlanInvasorBoImpl implements PlanInvasor {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
// otros atributos<br />
<br />
public Invasor findInvasorMasPeligroso() {<br />
<br />
// Realiza ciertos guarismos internos <br />
// para determinar la Fuerza, Velocidad y Destreza<br />
Fuerza fuerza = calcularFuerza();<br />
Velocidad velocidad = calcularVelocidad();<br />
Destreza destreza = calcularDestreza();<br />
<br />
// Utiliza los valores determinados para construir un Filtro<br />
Filtro filtro = new Filtro(fuerza, velocidad, destreza);<br />
<br />
// Llama al DAO con el filtro construido internamente<br />
return planInvasionDao.findInvasorPorFiltro(filtro);<br />
}<br />
// otros metodos<br />
<br />
}<br />
</code><br />
<br />
===El objetivo===<br />
<br />
El objetivo que nos planteamos es poder inspeccionar en un test que los valores del objeto Velocidad estén dentro de ciertos límites.<br />
<br />
===El problema===<br />
<br />
El problema que tenemos es que el objeto Velocidad se crea a partir de unos métodos privados de PlanInvasionBo y está dentro de otro objeto que se crea también dentro de PlanInvasionBo al que tampoco tenemos acceso.<br />
La única comunicación de este objeto con el exterior es en forma de parámetro a través de la llamada al método del DAO.<br />
<br />
=Una posible solución=<br />
<br />
Una posible solución a nuestro objetivo es capturar el parámetro Filtro que recibe el método del DAO que en el caso del test será un [[Mock Object]].<br />
<br />
=Captura de parámetro con EasyMock=<br />
<br />
La forma de capturar un parámetro con [[EasyMock]] es creando un objeto Capture parametrizado con la clase que va a capturar.<br />
Luego, en la maquetación del método, se utiliza el método estático EasyMock.capture que recibe al capturador.<br />
Luego de ejercitar el método podemos pedirle el valor capturado al capturador.<br />
<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao daoMock;<br />
<br />
protected void setUp() throws Exception {<br />
daoMock = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(daoMock);<br />
}<br />
<br />
public void testFindInvasorMasPeligroso() {<br />
<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
// Crear un Capture para utilizar en la maquetacion del metodo<br />
Capture<Filtro> caturaFiltro = new Capture<Filtro>();<br />
<br />
expect(mockDao.findInvasorPorFilro(capture(capturaFiltro)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
// los assert tipicos<br />
<br />
// Conseguir la referencia al filtro que llego como parametro<br />
// al metodo del daoMock<br />
Filtro filtro = capturaFiltro.getValue();<br />
<br />
assertNotNull(filtro);<br />
assertTrue(filtro.getVelocidad() < VELOCIDAD_MAXIMA);<br />
// El resto de los asserts necesarios sobre el filtro<br />
<br />
}<br />
}<br />
</code><br />
<br />
=Captura de parámetro con Mockito=<br />
<br />
(Agregar descripcion y codigo de Mockito)<br />
<br />
==Extensión del Matcher de Mockito==<br />
<br />
(Agregar descripcion y codigo del Matcher capturador)<br />
<br />
=Ver también=<br />
* [[Easy Mock]]<br />
* [[Mockito]]<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Captura_De_Parametros&diff=1142Captura De Parametros2008-10-10T17:54:34Z<p>Zabalet: /* Ver también */</p>
<hr />
<div>Hay situaciones en las que el estamos realizando un testeo con un [[Mock Object]] y queremos capturar un parámetro que recibe el mismo.<br />
<br />
Esta situación suele producirse cuando hay un objeto que se crea dentro de los objetos que estamos probando y llega como parámetro a algún [[Mock Object]]. Hay unas cuantas condiciones que podemos pedir a EasyMock y Mockito que validen como parámetro esperado como por ejemplo igualdad, expresiones regulares, no nulo, nulo, algunas comprobaciones con Strings y primitivos, etc. Pero incluso a veces esto no alcanza. El objeto fue creado dentro de otro objeto, es decir que no podemos ni inyectarlo desde fuera ni conseguirlo por medios naturales y queremos inspeccionar sus atributos y realizar una serie de asserts. Es ahí cuando conseguir una referencia al mismo nos resulta indispensable.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorMasPeligroso();<br />
}<br />
</code><br />
<br />
... la siguiente interfaz de DAO<br />
<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorPorFiltro(Filtro filtro);<br />
}<br />
</code><br />
<br />
... y el siguiente filtro<br />
<br />
<code java><br />
public class Filtro {<br />
<br />
private Fuerza fuerza;<br />
private Velocidad velocidad;<br />
private Destreza destreza;<br />
<br />
// sus metodos accesores<br />
}<br />
</code><br />
<br />
Dentro de la implementación de la clase PlanInvasionBo se crea una instancia de Filtro que se utiliza para comunicarse con el DAO pero no es externalizada en ningún momento (salvo como parámetro en la llamada al método del DAO) ni existe la posiblidad de inyectarla desde fuera.<br />
<br />
<code java><br />
public class PlanInvasorBoImpl implements PlanInvasor {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
// otros atributos<br />
<br />
public Invasor findInvasorMasPeligroso() {<br />
<br />
// Realiza ciertos guarismos internos <br />
// para determinar la Fuerza, Velocidad y Destreza<br />
Fuerza fuerza = calcularFuerza();<br />
Velocidad velocidad = calcularVelocidad();<br />
Destreza destreza = calcularDestreza();<br />
<br />
// Utiliza los valores determinados para construir un Filtro<br />
Filtro filtro = new Filtro(fuerza, velocidad, destreza);<br />
<br />
// Llama al DAO con el filtro construido internamente<br />
return planInvasionDao.findInvasorPorFiltro(filtro);<br />
}<br />
// otros metodos<br />
<br />
}<br />
</code><br />
<br />
===El objetivo===<br />
<br />
El objetivo que nos planteamos es poder inspeccionar en un test que los valores del objeto Velocidad estén dentro de ciertos límites.<br />
<br />
===El problema===<br />
<br />
El problema que tenemos es que el objeto Velocidad se crea a partir de unos métodos privados de PlanInvasionBo y está dentro de otro objeto que se crea también dentro de PlanInvasionBo al que tampoco tenemos acceso.<br />
La única comunicación de este objeto con el exterior es en forma de parámetro a través de la llamada al método del DAO.<br />
<br />
===Una posible solución===<br />
<br />
Una posible solución a nuestro objetivo es capturar el parámetro Filtro que recibe el método del DAO que en el caso del test será un [[Mock Object]].<br />
<br />
=Captura de parámetro con EasyMock=<br />
<br />
La forma de capturar un parámetro con [[EasyMock]] es creando un objeto Capture parametrizado con la clase que va a capturar.<br />
Luego, en la maquetación del método, se utiliza el método estático EasyMock.capture que recibe al capturador.<br />
Luego de ejercitar el método podemos pedirle el valor capturado al capturador.<br />
<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao daoMock;<br />
<br />
protected void setUp() throws Exception {<br />
daoMock = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(daoMock);<br />
}<br />
<br />
public void testFindInvasorMasPeligroso() {<br />
<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
// Crear un Capture para utilizar en la maquetacion del metodo<br />
Capture<Filtro> caturaFiltro = new Capture<Filtro>();<br />
<br />
expect(mockDao.findInvasorPorFilro(capture(capturaFiltro)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
// los assert tipicos<br />
<br />
// Conseguir la referencia al filtro que llego como parametro<br />
// al metodo del daoMock<br />
Filtro filtro = capturaFiltro.getValue();<br />
<br />
assertNotNull(filtro);<br />
assertTrue(filtro.getVelocidad() < VELOCIDAD_MAXIMA);<br />
// El resto de los asserts necesarios sobre el filtro<br />
<br />
}<br />
}<br />
</code><br />
<br />
=Captura de parámetro con Mockito=<br />
<br />
(Agregar descripcion y codigo de Mockito)<br />
<br />
==Extensión del Matcher de Mockito==<br />
<br />
(Agregar descripcion y codigo del Matcher capturador)<br />
<br />
=Ver también=<br />
* [[Easy Mock]]<br />
* [[Mockito]]<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Captura_De_Parametros&diff=1141Captura De Parametros2008-10-10T17:53:22Z<p>Zabalet: /* Ver también */</p>
<hr />
<div>Hay situaciones en las que el estamos realizando un testeo con un [[Mock Object]] y queremos capturar un parámetro que recibe el mismo.<br />
<br />
Esta situación suele producirse cuando hay un objeto que se crea dentro de los objetos que estamos probando y llega como parámetro a algún [[Mock Object]]. Hay unas cuantas condiciones que podemos pedir a EasyMock y Mockito que validen como parámetro esperado como por ejemplo igualdad, expresiones regulares, no nulo, nulo, algunas comprobaciones con Strings y primitivos, etc. Pero incluso a veces esto no alcanza. El objeto fue creado dentro de otro objeto, es decir que no podemos ni inyectarlo desde fuera ni conseguirlo por medios naturales y queremos inspeccionar sus atributos y realizar una serie de asserts. Es ahí cuando conseguir una referencia al mismo nos resulta indispensable.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorMasPeligroso();<br />
}<br />
</code><br />
<br />
... la siguiente interfaz de DAO<br />
<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorPorFiltro(Filtro filtro);<br />
}<br />
</code><br />
<br />
... y el siguiente filtro<br />
<br />
<code java><br />
public class Filtro {<br />
<br />
private Fuerza fuerza;<br />
private Velocidad velocidad;<br />
private Destreza destreza;<br />
<br />
// sus metodos accesores<br />
}<br />
</code><br />
<br />
Dentro de la implementación de la clase PlanInvasionBo se crea una instancia de Filtro que se utiliza para comunicarse con el DAO pero no es externalizada en ningún momento (salvo como parámetro en la llamada al método del DAO) ni existe la posiblidad de inyectarla desde fuera.<br />
<br />
<code java><br />
public class PlanInvasorBoImpl implements PlanInvasor {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
// otros atributos<br />
<br />
public Invasor findInvasorMasPeligroso() {<br />
<br />
// Realiza ciertos guarismos internos <br />
// para determinar la Fuerza, Velocidad y Destreza<br />
Fuerza fuerza = calcularFuerza();<br />
Velocidad velocidad = calcularVelocidad();<br />
Destreza destreza = calcularDestreza();<br />
<br />
// Utiliza los valores determinados para construir un Filtro<br />
Filtro filtro = new Filtro(fuerza, velocidad, destreza);<br />
<br />
// Llama al DAO con el filtro construido internamente<br />
return planInvasionDao.findInvasorPorFiltro(filtro);<br />
}<br />
// otros metodos<br />
<br />
}<br />
</code><br />
<br />
===El objetivo===<br />
<br />
El objetivo que nos planteamos es poder inspeccionar en un test que los valores del objeto Velocidad estén dentro de ciertos límites.<br />
<br />
===El problema===<br />
<br />
El problema que tenemos es que el objeto Velocidad se crea a partir de unos métodos privados de PlanInvasionBo y está dentro de otro objeto que se crea también dentro de PlanInvasionBo al que tampoco tenemos acceso.<br />
La única comunicación de este objeto con el exterior es en forma de parámetro a través de la llamada al método del DAO.<br />
<br />
===Una posible solución===<br />
<br />
Una posible solución a nuestro objetivo es capturar el parámetro Filtro que recibe el método del DAO que en el caso del test será un [[Mock Object]].<br />
<br />
=Captura de parámetro con EasyMock=<br />
<br />
La forma de capturar un parámetro con [[EasyMock]] es creando un objeto Capture parametrizado con la clase que va a capturar.<br />
Luego, en la maquetación del método, se utiliza el método estático EasyMock.capture que recibe al capturador.<br />
Luego de ejercitar el método podemos pedirle el valor capturado al capturador.<br />
<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao daoMock;<br />
<br />
protected void setUp() throws Exception {<br />
daoMock = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(daoMock);<br />
}<br />
<br />
public void testFindInvasorMasPeligroso() {<br />
<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
// Crear un Capture para utilizar en la maquetacion del metodo<br />
Capture<Filtro> caturaFiltro = new Capture<Filtro>();<br />
<br />
expect(mockDao.findInvasorPorFilro(capture(capturaFiltro)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
// los assert tipicos<br />
<br />
// Conseguir la referencia al filtro que llego como parametro<br />
// al metodo del daoMock<br />
Filtro filtro = capturaFiltro.getValue();<br />
<br />
assertNotNull(filtro);<br />
assertTrue(filtro.getVelocidad() < VELOCIDAD_MAXIMA);<br />
// El resto de los asserts necesarios sobre el filtro<br />
<br />
}<br />
}<br />
</code><br />
<br />
=Captura de parámetro con Mockito=<br />
<br />
(Agregar descripcion y codigo de Mockito)<br />
<br />
==Extensión del Matcher de Mockito==<br />
<br />
(Agregar descripcion y codigo del Matcher capturador)<br />
<br />
==Ver también==<br />
* [[Easy Mock]]<br />
* [[Mockito]]<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Captura_De_Parametros&diff=1140Captura De Parametros2008-10-10T17:52:34Z<p>Zabalet: /* Una posible solución */</p>
<hr />
<div>Hay situaciones en las que el estamos realizando un testeo con un [[Mock Object]] y queremos capturar un parámetro que recibe el mismo.<br />
<br />
Esta situación suele producirse cuando hay un objeto que se crea dentro de los objetos que estamos probando y llega como parámetro a algún [[Mock Object]]. Hay unas cuantas condiciones que podemos pedir a EasyMock y Mockito que validen como parámetro esperado como por ejemplo igualdad, expresiones regulares, no nulo, nulo, algunas comprobaciones con Strings y primitivos, etc. Pero incluso a veces esto no alcanza. El objeto fue creado dentro de otro objeto, es decir que no podemos ni inyectarlo desde fuera ni conseguirlo por medios naturales y queremos inspeccionar sus atributos y realizar una serie de asserts. Es ahí cuando conseguir una referencia al mismo nos resulta indispensable.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorMasPeligroso();<br />
}<br />
</code><br />
<br />
... la siguiente interfaz de DAO<br />
<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorPorFiltro(Filtro filtro);<br />
}<br />
</code><br />
<br />
... y el siguiente filtro<br />
<br />
<code java><br />
public class Filtro {<br />
<br />
private Fuerza fuerza;<br />
private Velocidad velocidad;<br />
private Destreza destreza;<br />
<br />
// sus metodos accesores<br />
}<br />
</code><br />
<br />
Dentro de la implementación de la clase PlanInvasionBo se crea una instancia de Filtro que se utiliza para comunicarse con el DAO pero no es externalizada en ningún momento (salvo como parámetro en la llamada al método del DAO) ni existe la posiblidad de inyectarla desde fuera.<br />
<br />
<code java><br />
public class PlanInvasorBoImpl implements PlanInvasor {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
// otros atributos<br />
<br />
public Invasor findInvasorMasPeligroso() {<br />
<br />
// Realiza ciertos guarismos internos <br />
// para determinar la Fuerza, Velocidad y Destreza<br />
Fuerza fuerza = calcularFuerza();<br />
Velocidad velocidad = calcularVelocidad();<br />
Destreza destreza = calcularDestreza();<br />
<br />
// Utiliza los valores determinados para construir un Filtro<br />
Filtro filtro = new Filtro(fuerza, velocidad, destreza);<br />
<br />
// Llama al DAO con el filtro construido internamente<br />
return planInvasionDao.findInvasorPorFiltro(filtro);<br />
}<br />
// otros metodos<br />
<br />
}<br />
</code><br />
<br />
===El objetivo===<br />
<br />
El objetivo que nos planteamos es poder inspeccionar en un test que los valores del objeto Velocidad estén dentro de ciertos límites.<br />
<br />
===El problema===<br />
<br />
El problema que tenemos es que el objeto Velocidad se crea a partir de unos métodos privados de PlanInvasionBo y está dentro de otro objeto que se crea también dentro de PlanInvasionBo al que tampoco tenemos acceso.<br />
La única comunicación de este objeto con el exterior es en forma de parámetro a través de la llamada al método del DAO.<br />
<br />
===Una posible solución===<br />
<br />
Una posible solución a nuestro objetivo es capturar el parámetro Filtro que recibe el método del DAO que en el caso del test será un [[Mock Object]].<br />
<br />
=Captura de parámetro con EasyMock=<br />
<br />
La forma de capturar un parámetro con [[EasyMock]] es creando un objeto Capture parametrizado con la clase que va a capturar.<br />
Luego, en la maquetación del método, se utiliza el método estático EasyMock.capture que recibe al capturador.<br />
Luego de ejercitar el método podemos pedirle el valor capturado al capturador.<br />
<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao daoMock;<br />
<br />
protected void setUp() throws Exception {<br />
daoMock = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(daoMock);<br />
}<br />
<br />
public void testFindInvasorMasPeligroso() {<br />
<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
// Crear un Capture para utilizar en la maquetacion del metodo<br />
Capture<Filtro> caturaFiltro = new Capture<Filtro>();<br />
<br />
expect(mockDao.findInvasorPorFilro(capture(capturaFiltro)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
// los assert tipicos<br />
<br />
// Conseguir la referencia al filtro que llego como parametro<br />
// al metodo del daoMock<br />
Filtro filtro = capturaFiltro.getValue();<br />
<br />
assertNotNull(filtro);<br />
assertTrue(filtro.getVelocidad() < VELOCIDAD_MAXIMA);<br />
// El resto de los asserts necesarios sobre el filtro<br />
<br />
}<br />
}<br />
</code><br />
<br />
=Captura de parámetro con Mockito=<br />
<br />
(Agregar descripcion y codigo de Mockito)<br />
<br />
==Extensión del Matcher de Mockito==<br />
<br />
(Agregar descripcion y codigo del Matcher capturador)<br />
<br />
==Ver también==<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]<br />
* [[Captura De Parametros]]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Captura_De_Parametros&diff=1139Captura De Parametros2008-10-10T17:50:40Z<p>Zabalet: /* El problema */</p>
<hr />
<div>Hay situaciones en las que el estamos realizando un testeo con un [[Mock Object]] y queremos capturar un parámetro que recibe el mismo.<br />
<br />
Esta situación suele producirse cuando hay un objeto que se crea dentro de los objetos que estamos probando y llega como parámetro a algún [[Mock Object]]. Hay unas cuantas condiciones que podemos pedir a EasyMock y Mockito que validen como parámetro esperado como por ejemplo igualdad, expresiones regulares, no nulo, nulo, algunas comprobaciones con Strings y primitivos, etc. Pero incluso a veces esto no alcanza. El objeto fue creado dentro de otro objeto, es decir que no podemos ni inyectarlo desde fuera ni conseguirlo por medios naturales y queremos inspeccionar sus atributos y realizar una serie de asserts. Es ahí cuando conseguir una referencia al mismo nos resulta indispensable.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorMasPeligroso();<br />
}<br />
</code><br />
<br />
... la siguiente interfaz de DAO<br />
<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorPorFiltro(Filtro filtro);<br />
}<br />
</code><br />
<br />
... y el siguiente filtro<br />
<br />
<code java><br />
public class Filtro {<br />
<br />
private Fuerza fuerza;<br />
private Velocidad velocidad;<br />
private Destreza destreza;<br />
<br />
// sus metodos accesores<br />
}<br />
</code><br />
<br />
Dentro de la implementación de la clase PlanInvasionBo se crea una instancia de Filtro que se utiliza para comunicarse con el DAO pero no es externalizada en ningún momento (salvo como parámetro en la llamada al método del DAO) ni existe la posiblidad de inyectarla desde fuera.<br />
<br />
<code java><br />
public class PlanInvasorBoImpl implements PlanInvasor {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
// otros atributos<br />
<br />
public Invasor findInvasorMasPeligroso() {<br />
<br />
// Realiza ciertos guarismos internos <br />
// para determinar la Fuerza, Velocidad y Destreza<br />
Fuerza fuerza = calcularFuerza();<br />
Velocidad velocidad = calcularVelocidad();<br />
Destreza destreza = calcularDestreza();<br />
<br />
// Utiliza los valores determinados para construir un Filtro<br />
Filtro filtro = new Filtro(fuerza, velocidad, destreza);<br />
<br />
// Llama al DAO con el filtro construido internamente<br />
return planInvasionDao.findInvasorPorFiltro(filtro);<br />
}<br />
// otros metodos<br />
<br />
}<br />
</code><br />
<br />
===El objetivo===<br />
<br />
El objetivo que nos planteamos es poder inspeccionar en un test que los valores del objeto Velocidad estén dentro de ciertos límites.<br />
<br />
===El problema===<br />
<br />
El problema que tenemos es que el objeto Velocidad se crea a partir de unos métodos privados de PlanInvasionBo y está dentro de otro objeto que se crea también dentro de PlanInvasionBo al que tampoco tenemos acceso.<br />
La única comunicación de este objeto con el exterior es en forma de parámetro a través de la llamada al método del DAO.<br />
<br />
===Una posible solución===<br />
<br />
Tenemos así la clase PlanInvasionBoImpl que la implementa. Esta clase se comunica con un [[DAO]] para realizar la búsqueda del objeto de dominio Invasor. Luego de obtenerlo, lo convierte a un InvasorDto y lo devuelve.<br />
<br />
=Captura de parámetro con EasyMock=<br />
<br />
La forma de capturar un parámetro con [[EasyMock]] es creando un objeto Capture parametrizado con la clase que va a capturar.<br />
Luego, en la maquetación del método, se utiliza el método estático EasyMock.capture que recibe al capturador.<br />
Luego de ejercitar el método podemos pedirle el valor capturado al capturador.<br />
<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao daoMock;<br />
<br />
protected void setUp() throws Exception {<br />
daoMock = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(daoMock);<br />
}<br />
<br />
public void testFindInvasorMasPeligroso() {<br />
<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
// Crear un Capture para utilizar en la maquetacion del metodo<br />
Capture<Filtro> caturaFiltro = new Capture<Filtro>();<br />
<br />
expect(mockDao.findInvasorPorFilro(capture(capturaFiltro)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
// los assert tipicos<br />
<br />
// Conseguir la referencia al filtro que llego como parametro<br />
// al metodo del daoMock<br />
Filtro filtro = capturaFiltro.getValue();<br />
<br />
assertNotNull(filtro);<br />
assertTrue(filtro.getVelocidad() < VELOCIDAD_MAXIMA);<br />
// El resto de los asserts necesarios sobre el filtro<br />
<br />
}<br />
}<br />
</code><br />
<br />
=Captura de parámetro con Mockito=<br />
<br />
(Agregar descripcion y codigo de Mockito)<br />
<br />
==Extensión del Matcher de Mockito==<br />
<br />
(Agregar descripcion y codigo del Matcher capturador)<br />
<br />
==Ver también==<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]<br />
* [[Captura De Parametros]]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Captura_De_Parametros&diff=1138Captura De Parametros2008-10-10T17:49:30Z<p>Zabalet: /* El escenario */</p>
<hr />
<div>Hay situaciones en las que el estamos realizando un testeo con un [[Mock Object]] y queremos capturar un parámetro que recibe el mismo.<br />
<br />
Esta situación suele producirse cuando hay un objeto que se crea dentro de los objetos que estamos probando y llega como parámetro a algún [[Mock Object]]. Hay unas cuantas condiciones que podemos pedir a EasyMock y Mockito que validen como parámetro esperado como por ejemplo igualdad, expresiones regulares, no nulo, nulo, algunas comprobaciones con Strings y primitivos, etc. Pero incluso a veces esto no alcanza. El objeto fue creado dentro de otro objeto, es decir que no podemos ni inyectarlo desde fuera ni conseguirlo por medios naturales y queremos inspeccionar sus atributos y realizar una serie de asserts. Es ahí cuando conseguir una referencia al mismo nos resulta indispensable.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorMasPeligroso();<br />
}<br />
</code><br />
<br />
... la siguiente interfaz de DAO<br />
<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorPorFiltro(Filtro filtro);<br />
}<br />
</code><br />
<br />
... y el siguiente filtro<br />
<br />
<code java><br />
public class Filtro {<br />
<br />
private Fuerza fuerza;<br />
private Velocidad velocidad;<br />
private Destreza destreza;<br />
<br />
// sus metodos accesores<br />
}<br />
</code><br />
<br />
Dentro de la implementación de la clase PlanInvasionBo se crea una instancia de Filtro que se utiliza para comunicarse con el DAO pero no es externalizada en ningún momento (salvo como parámetro en la llamada al método del DAO) ni existe la posiblidad de inyectarla desde fuera.<br />
<br />
<code java><br />
public class PlanInvasorBoImpl implements PlanInvasor {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
// otros atributos<br />
<br />
public Invasor findInvasorMasPeligroso() {<br />
<br />
// Realiza ciertos guarismos internos <br />
// para determinar la Fuerza, Velocidad y Destreza<br />
Fuerza fuerza = calcularFuerza();<br />
Velocidad velocidad = calcularVelocidad();<br />
Destreza destreza = calcularDestreza();<br />
<br />
// Utiliza los valores determinados para construir un Filtro<br />
Filtro filtro = new Filtro(fuerza, velocidad, destreza);<br />
<br />
// Llama al DAO con el filtro construido internamente<br />
return planInvasionDao.findInvasorPorFiltro(filtro);<br />
}<br />
// otros metodos<br />
<br />
}<br />
</code><br />
<br />
===El objetivo===<br />
<br />
El objetivo que nos planteamos es poder inspeccionar en un test que los valores del objeto Velocidad estén dentro de ciertos límites.<br />
<br />
===El problema===<br />
<br />
El problema que tenemos es que el objeto Velocidad se crea a partir de unos métodos privados de PlanInvasionBo y está dentro de otro objeto que se crea también dentro de PlanInvasionBo al que tampoco tenemos acceso.<br />
La única comunicación de este objeto con el exterior es a través de la llamada al <br />
<br />
===Una posible solución===<br />
<br />
Tenemos así la clase PlanInvasionBoImpl que la implementa. Esta clase se comunica con un [[DAO]] para realizar la búsqueda del objeto de dominio Invasor. Luego de obtenerlo, lo convierte a un InvasorDto y lo devuelve.<br />
<br />
=Captura de parámetro con EasyMock=<br />
<br />
La forma de capturar un parámetro con [[EasyMock]] es creando un objeto Capture parametrizado con la clase que va a capturar.<br />
Luego, en la maquetación del método, se utiliza el método estático EasyMock.capture que recibe al capturador.<br />
Luego de ejercitar el método podemos pedirle el valor capturado al capturador.<br />
<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao daoMock;<br />
<br />
protected void setUp() throws Exception {<br />
daoMock = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(daoMock);<br />
}<br />
<br />
public void testFindInvasorMasPeligroso() {<br />
<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
// Crear un Capture para utilizar en la maquetacion del metodo<br />
Capture<Filtro> caturaFiltro = new Capture<Filtro>();<br />
<br />
expect(mockDao.findInvasorPorFilro(capture(capturaFiltro)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
// los assert tipicos<br />
<br />
// Conseguir la referencia al filtro que llego como parametro<br />
// al metodo del daoMock<br />
Filtro filtro = capturaFiltro.getValue();<br />
<br />
assertNotNull(filtro);<br />
assertTrue(filtro.getVelocidad() < VELOCIDAD_MAXIMA);<br />
// El resto de los asserts necesarios sobre el filtro<br />
<br />
}<br />
}<br />
</code><br />
<br />
=Captura de parámetro con Mockito=<br />
<br />
(Agregar descripcion y codigo de Mockito)<br />
<br />
==Extensión del Matcher de Mockito==<br />
<br />
(Agregar descripcion y codigo del Matcher capturador)<br />
<br />
==Ver también==<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]<br />
* [[Captura De Parametros]]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Captura_De_Parametros&diff=1137Captura De Parametros2008-10-10T17:46:48Z<p>Zabalet: Ver también</p>
<hr />
<div>Hay situaciones en las que el estamos realizando un testeo con un [[Mock Object]] y queremos capturar un parámetro que recibe el mismo.<br />
<br />
Esta situación suele producirse cuando hay un objeto que se crea dentro de los objetos que estamos probando y llega como parámetro a algún [[Mock Object]]. Hay unas cuantas condiciones que podemos pedir a EasyMock y Mockito que validen como parámetro esperado como por ejemplo igualdad, expresiones regulares, no nulo, nulo, algunas comprobaciones con Strings y primitivos, etc. Pero incluso a veces esto no alcanza. El objeto fue creado dentro de otro objeto, es decir que no podemos ni inyectarlo desde fuera ni conseguirlo por medios naturales y queremos inspeccionar sus atributos y realizar una serie de asserts. Es ahí cuando conseguir una referencia al mismo nos resulta indispensable.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorMasPeligroso();<br />
}<br />
</code><br />
<br />
... la siguiente interfaz de DAO<br />
<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorPorFiltro(Filtro filtro);<br />
}<br />
</code><br />
<br />
... y el siguiente filtro<br />
<br />
<code java><br />
public class Filtro {<br />
<br />
private Fuerza fuerza;<br />
private Velocidad velocidad;<br />
private Destreza destreza;<br />
<br />
// sus metodos accesores<br />
}<br />
</code><br />
<br />
La complicación comienza en la implementación de la clase PlanInvasionBo:<br />
<br />
<code java><br />
public class PlanInvasorBoImpl implements PlanInvasor {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
// otros atributos<br />
<br />
public Invasor findInvasorMasPeligroso() {<br />
<br />
// Realiza ciertos guarismos internos <br />
// para determinar la Fuerza, Velocidad y Destreza<br />
Fuerza fuerza = calcularFuerza();<br />
Velocidad velocidad = calcularVelocidad();<br />
Destreza destreza = calcularDestreza();<br />
<br />
// Utiliza los valores determinados para construir un Filtro<br />
Filtro filtro = new Filtro(fuerza, velocidad, destreza);<br />
<br />
// Llama al DAO con el filtro construido internamente<br />
return planInvasionDao.findInvasorPorFiltro(filtro);<br />
}<br />
// otros metodos<br />
<br />
}<br />
</code><br />
<br />
===El objetivo===<br />
<br />
El objetivo que nos planteamos es poder inspeccionar en un test que los valores del objeto Velocidad estén dentro de ciertos límites.<br />
<br />
===El problema===<br />
<br />
El problema que tenemos es que el objeto Velocidad se crea a partir de unos métodos privados de PlanInvasionBo y está dentro de otro objeto que se crea también dentro de PlanInvasionBo al que tampoco tenemos acceso.<br />
La única comunicación de este objeto con el exterior es a través de la llamada al <br />
<br />
===Una posible solución===<br />
<br />
Tenemos así la clase PlanInvasionBoImpl que la implementa. Esta clase se comunica con un [[DAO]] para realizar la búsqueda del objeto de dominio Invasor. Luego de obtenerlo, lo convierte a un InvasorDto y lo devuelve.<br />
<br />
=Captura de parámetro con EasyMock=<br />
<br />
La forma de capturar un parámetro con [[EasyMock]] es creando un objeto Capture parametrizado con la clase que va a capturar.<br />
Luego, en la maquetación del método, se utiliza el método estático EasyMock.capture que recibe al capturador.<br />
Luego de ejercitar el método podemos pedirle el valor capturado al capturador.<br />
<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao daoMock;<br />
<br />
protected void setUp() throws Exception {<br />
daoMock = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(daoMock);<br />
}<br />
<br />
public void testFindInvasorMasPeligroso() {<br />
<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
// Crear un Capture para utilizar en la maquetacion del metodo<br />
Capture<Filtro> caturaFiltro = new Capture<Filtro>();<br />
<br />
expect(mockDao.findInvasorPorFilro(capture(capturaFiltro)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
// los assert tipicos<br />
<br />
// Conseguir la referencia al filtro que llego como parametro<br />
// al metodo del daoMock<br />
Filtro filtro = capturaFiltro.getValue();<br />
<br />
assertNotNull(filtro);<br />
assertTrue(filtro.getVelocidad() < VELOCIDAD_MAXIMA);<br />
// El resto de los asserts necesarios sobre el filtro<br />
<br />
}<br />
}<br />
</code><br />
<br />
=Captura de parámetro con Mockito=<br />
<br />
(Agregar descripcion y codigo de Mockito)<br />
<br />
==Extensión del Matcher de Mockito==<br />
<br />
(Agregar descripcion y codigo del Matcher capturador)<br />
<br />
==Ver también==<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]<br />
* [[Captura De Parametros]]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Mockito&diff=1136Mockito2008-10-10T15:42:24Z<p>Zabalet: /* Ver también */</p>
<hr />
<div>Mockito es una librería [[Java]] para la creación de [[Mock Object]] muy usados para el testeo unitario en [[Test Driven Development]], basado en [[EasyMock]]. <br />
<br />
Mockito fue creado con el objetivo de simplificar y solucionar algunos de los temas antes mencionados. EasyMock y Mockito puede hacer exactamente las mismas cosas, pero Mockito tiene un API más natural y práctico de usar.<br />
<br />
==Características principales==<br />
# Se pueden crear mocks de interfaces y clases concretas.<br />
# Verificación de invocaciones (cantidad exacta, al menos una vez, órden de invocación, etc.)<br />
# El stack trace se mantiene limpio, ya que los errores ocurren en los assert que se hagan (y no dentro del método bajo prueba, como en EasyMock).<br />
# Un API más clara para crear stubs y verificaciones<br />
<br />
==Ejemplo de uso==<br />
<code java><br />
import static org.mockito.Mockito.*;<br />
.....<br />
//creamos el mock y el stub<br />
ArrayList instance = mock(ArrayList.class);<br />
doReturn("hola mundo").when(instance).get(0);<br />
<br />
//ejecutamos la lógica a probar<br />
instance.get(0); <br />
<br />
//verificamos que se hayan invocado los métodos<br />
verify(instance).get(0);<br />
</code><br />
<br />
==Ver también==<br />
* [[EasyMock]]<br />
* [http://www.dosideas.com/descargas/doc_download/11-demo-de-mockito.html Proyecto de ejemplos con Mockito]<br />
* [http://www.dosideas.com/java/242-mockito-o-basta-de-easymock.html Introducción a Mockito]<br />
* [[Captura De Parametros]]</div>Zabalethttps://dosideas.com/wiki/index.php?title=EasyMock&diff=1135EasyMock2008-10-10T15:41:39Z<p>Zabalet: /* Ver también */</p>
<hr />
<div>EasyMock proporciona [[Mock Object]] para interfaces durante la [[Prueba Unitaria]] mediante la generación de estas sobre la marcha utilizando mecanismo de Proxy de Java. Debido al estilo único de registro de espectativas en EasyMock, la mayoría de [[Refactor]]'s no afectará a los objetos Mock. Así EasyMock es perfecto para [[Test Driven Development]].<br />
<br />
[[EasyMock]] es software de código abierto disponible bajo los términos de la licencia MIT.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorById(Long id);<br />
}<br />
</code><br />
<br />
Tenemos así la clase PlanInvasionBoImpl que la implementa. Esta clase se comunica con un [[DAO]] para realizar la búsqueda del objeto de dominio Invasor. Luego de obtenerlo, lo convierte a un InvasorDto y lo devuelve.<br />
<br />
El Dao en cuestión es de la forma:<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorById(Long id);<br />
}<br />
</code><br />
<br />
Usamos [[Spring Framework]] para inyectar la dependencia que tiene nuestro InvasorBoImpl con el Dao.<br />
<br />
As, nuestra clase InvasorBoImpl queda bastante simple:<br />
<code java><br />
public class PlanInvasionBoImpl implements PlanInvasionBo {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
<br />
public InvasorDto findInvasorById(Long id) {<br />
Invasor invasor = planInvasionDao.findInvasorById(id);<br />
InvasorDto invasorDto = new InvasorDto(invasor.getId(), invasor.getNombre());<br />
return invasorDto;<br />
}<br />
//Getters y setters de planInvasioDao a continuacion...<br />
}<br />
</code><br />
<br />
===Creando el test de PlanInvasioBoImpl===<br />
<br />
Crearemos entonces un test unitario usando [[JUnit]] para nuestro método ''PlanInvasioBoImpl.findInvasioById()''.<br />
<br />
Obviamente, no queremos testear a nuestro Dao (recordemos la definición de [[Prueba Unitaria]]!), así que deberemos crear un [[Mock Object]] para simularlo.<br />
<br />
La creación de mocks es muy simple con EasyMock. Los pasos básicos son:<br />
<br />
# Crear el mock (usualmente, en el setUp() del test<br />
# "Grabarle" el comportamiento esperado<br />
# Iniciar el mock (a través del método replay())<br />
# Ejecutar nuestro método a testear<br />
# Verificar el mock (a través del método verify())<br />
# Realizar otros assert nuestros<br />
<br />
Así, nuestro test completo quedaría:<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao mockDao;<br />
<br />
protected void setUp() throws Exception {<br />
mockDao = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(mockDao);<br />
}<br />
<br />
public void testFindInvasorById() {<br />
Long id = 1L;<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
expect(mockDao.findInvasorById(id)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
assertEquals(invasor.getId(), resultado.getId());<br />
assertEquals(invasor.getNombre(), resultado.getNombre());<br />
}<br />
}<br />
</code><br />
<br />
===Y lo que ocurre es lo siguiente...===<br />
Como vemos, realizamos un import static de varios métodos de la clase EasyMock (si, necesitamos JSE 5 para la última versión de EasyMock)<br />
<br />
En el método setUp() creamos el mock. Los mocks se crean a partir de interfaces. Así, le asignamos la dependencia a nuestro Bo a testear.<br />
<br />
Finalmente, ya en testFindInvasionById() y antes de ejecutar el método a testear, grabamos el comportamiento que deseamos de nuestro mock. La línea "expect(....)" puede leerse como:<br />
<br />
"Esperar que se invoque a mockDao.findInvasorById() con el parámetro id, y entonces devolver invasor".<br />
<br />
Por último, la llamada a "verify" verifica que se las invocaciones a nuestro mock hayan ocurrido, en el orden que dijimos.<br />
<br />
== EasyMock 2.4 ==<br />
* Se agregaron los métodos resetToNice/Default/Strict<br />
* Se hicieron más flexibles los cmoparadores genéricos<br />
* Los mocks son serializables<br />
* Se pueden crear mocks thread-safe<br />
<br />
==Ver también==<br />
* [[Mockito]]<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]<br />
* [[Captura De Parametros]]</div>Zabalethttps://dosideas.com/wiki/index.php?title=EasyMock&diff=1134EasyMock2008-10-10T11:13:33Z<p>Zabalet: /* Ver también */</p>
<hr />
<div>EasyMock proporciona [[Mock Object]] para interfaces durante la [[Prueba Unitaria]] mediante la generación de estas sobre la marcha utilizando mecanismo de Proxy de Java. Debido al estilo único de registro de espectativas en EasyMock, la mayoría de [[Refactor]]'s no afectará a los objetos Mock. Así EasyMock es perfecto para [[Test Driven Development]].<br />
<br />
[[EasyMock]] es software de código abierto disponible bajo los términos de la licencia MIT.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorById(Long id);<br />
}<br />
</code><br />
<br />
Tenemos así la clase PlanInvasionBoImpl que la implementa. Esta clase se comunica con un [[DAO]] para realizar la búsqueda del objeto de dominio Invasor. Luego de obtenerlo, lo convierte a un InvasorDto y lo devuelve.<br />
<br />
El Dao en cuestión es de la forma:<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorById(Long id);<br />
}<br />
</code><br />
<br />
Usamos [[Spring Framework]] para inyectar la dependencia que tiene nuestro InvasorBoImpl con el Dao.<br />
<br />
As, nuestra clase InvasorBoImpl queda bastante simple:<br />
<code java><br />
public class PlanInvasionBoImpl implements PlanInvasionBo {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
<br />
public InvasorDto findInvasorById(Long id) {<br />
Invasor invasor = planInvasionDao.findInvasorById(id);<br />
InvasorDto invasorDto = new InvasorDto(invasor.getId(), invasor.getNombre());<br />
return invasorDto;<br />
}<br />
//Getters y setters de planInvasioDao a continuacion...<br />
}<br />
</code><br />
<br />
===Creando el test de PlanInvasioBoImpl===<br />
<br />
Crearemos entonces un test unitario usando [[JUnit]] para nuestro método ''PlanInvasioBoImpl.findInvasioById()''.<br />
<br />
Obviamente, no queremos testear a nuestro Dao (recordemos la definición de [[Prueba Unitaria]]!), así que deberemos crear un [[Mock Object]] para simularlo.<br />
<br />
La creación de mocks es muy simple con EasyMock. Los pasos básicos son:<br />
<br />
# Crear el mock (usualmente, en el setUp() del test<br />
# "Grabarle" el comportamiento esperado<br />
# Iniciar el mock (a través del método replay())<br />
# Ejecutar nuestro método a testear<br />
# Verificar el mock (a través del método verify())<br />
# Realizar otros assert nuestros<br />
<br />
Así, nuestro test completo quedaría:<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao mockDao;<br />
<br />
protected void setUp() throws Exception {<br />
mockDao = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(mockDao);<br />
}<br />
<br />
public void testFindInvasorById() {<br />
Long id = 1L;<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
expect(mockDao.findInvasorById(id)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
assertEquals(invasor.getId(), resultado.getId());<br />
assertEquals(invasor.getNombre(), resultado.getNombre());<br />
}<br />
}<br />
</code><br />
<br />
===Y lo que ocurre es lo siguiente...===<br />
Como vemos, realizamos un import static de varios métodos de la clase EasyMock (si, necesitamos JSE 5 para la última versión de EasyMock)<br />
<br />
En el método setUp() creamos el mock. Los mocks se crean a partir de interfaces. Así, le asignamos la dependencia a nuestro Bo a testear.<br />
<br />
Finalmente, ya en testFindInvasionById() y antes de ejecutar el método a testear, grabamos el comportamiento que deseamos de nuestro mock. La línea "expect(....)" puede leerse como:<br />
<br />
"Esperar que se invoque a mockDao.findInvasorById() con el parámetro id, y entonces devolver invasor".<br />
<br />
Por último, la llamada a "verify" verifica que se las invocaciones a nuestro mock hayan ocurrido, en el orden que dijimos.<br />
<br />
== EasyMock 2.4 ==<br />
* Se agregaron los métodos resetToNice/Default/Strict<br />
* Se hicieron más flexibles los cmoparadores genéricos<br />
* Los mocks son serializables<br />
* Se pueden crear mocks thread-safe<br />
<br />
==Ver también==<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]<br />
* [[Captura De Parametros]]</div>Zabalethttps://dosideas.com/wiki/index.php?title=EasyMock&diff=1105EasyMock2008-10-02T12:39:15Z<p>Zabalet: /* Ver también */</p>
<hr />
<div>EasyMock proporciona [[Mock Object]] para interfaces durante la [[Prueba Unitaria]] mediante la generación de estas sobre la marcha utilizando mecanismo de Proxy de Java. Debido al estilo único de registro de espectativas en EasyMock, la mayoría de [[Refactor]]'s no afectará a los objetos Mock. Así EasyMock es perfecto para [[Test Driven Development]].<br />
<br />
[[EasyMock]] es software de código abierto disponible bajo los términos de la licencia MIT.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorById(Long id);<br />
}<br />
</code><br />
<br />
Tenemos así la clase PlanInvasionBoImpl que la implementa. Esta clase se comunica con un [[DAO]] para realizar la búsqueda del objeto de dominio Invasor. Luego de obtenerlo, lo convierte a un InvasorDto y lo devuelve.<br />
<br />
El Dao en cuestión es de la forma:<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorById(Long id);<br />
}<br />
</code><br />
<br />
Usamos [[Spring Framework]] para inyectar la dependencia que tiene nuestro InvasorBoImpl con el Dao.<br />
<br />
As, nuestra clase InvasorBoImpl queda bastante simple:<br />
<code java><br />
public class PlanInvasionBoImpl implements PlanInvasionBo {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
<br />
public InvasorDto findInvasorById(Long id) {<br />
Invasor invasor = planInvasionDao.findInvasorById(id);<br />
InvasorDto invasorDto = new InvasorDto(invasor.getId(), invasor.getNombre());<br />
return invasorDto;<br />
}<br />
//Getters y setters de planInvasioDao a continuacion...<br />
}<br />
</code><br />
<br />
===Creando el test de PlanInvasioBoImpl===<br />
<br />
Crearemos entonces un test unitario usando [[JUnit]] para nuestro método ''PlanInvasioBoImpl.findInvasioById()''.<br />
<br />
Obviamente, no queremos testear a nuestro Dao (recordemos la definición de [[Prueba Unitaria]]!), así que deberemos crear un [[MockObject]] para simularlo.<br />
<br />
La creación de mocks es muy simple con EasyMock. Los pasos básicos son:<br />
<br />
# Crear el mock (usualmente, en el setUp() del test<br />
# "Grabarle" el comportamiento esperado<br />
# Iniciar el mock (a través del método replay())<br />
# Ejecutar nuestro método a testear<br />
# Verificar el mock (a través del método verify())<br />
# Realizar otros assert nuestros<br />
<br />
Así, nuestro test completo quedaría:<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao mockDao;<br />
<br />
protected void setUp() throws Exception {<br />
mockDao = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(mockDao);<br />
}<br />
<br />
public void testFindInvasorById() {<br />
Long id = 1L;<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
expect(mockDao.findInvasorById(id)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
assertEquals(invasor.getId(), resultado.getId());<br />
assertEquals(invasor.getNombre(), resultado.getNombre());<br />
}<br />
}<br />
</code><br />
<br />
===Y lo que ocurre es lo siguiente...===<br />
Como vemos, realizamos un import static de varios métodos de la clase EasyMock (si, necesitamos JSE 5 para la última versión de EasyMock)<br />
<br />
En el método setUp() creamos el mock. Los mocks se crean a partir de interfaces. Así, le asignamos la dependencia a nuestro Bo a testear.<br />
<br />
Finalmente, ya en testFindInvasionById() y antes de ejecutar el método a testear, grabamos el comportamiento que deseamos de nuestro mock. La línea "expect(....)" puede leerse como:<br />
<br />
"Esperar que se invoque a mockDao.findInvasorById() con el parámetro id, y entonces devolver invasor".<br />
<br />
Por último, la llamada a "verify" verifica que se las invocaciones a nuestro mock hayan ocurrido, en el orden que dijimos.<br />
<br />
==Ver también==<br />
* [[EasyMock: Cambios de la version 2.4]]<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]</div>Zabalethttps://dosideas.com/wiki/index.php?title=EasyMock&diff=1104EasyMock2008-10-02T12:38:39Z<p>Zabalet: /* Ver también */</p>
<hr />
<div>EasyMock proporciona [[Mock Object]] para interfaces durante la [[Prueba Unitaria]] mediante la generación de estas sobre la marcha utilizando mecanismo de Proxy de Java. Debido al estilo único de registro de espectativas en EasyMock, la mayoría de [[Refactor]]'s no afectará a los objetos Mock. Así EasyMock es perfecto para [[Test Driven Development]].<br />
<br />
[[EasyMock]] es software de código abierto disponible bajo los términos de la licencia MIT.<br />
<br />
==Ejemplo==<br />
===El escenario===<br />
Supongamos la siguiente interfaz de negocio:<br />
<br />
<code java><br />
public interface PlanInvasionBo {<br />
public InvasorDto findInvasorById(Long id);<br />
}<br />
</code><br />
<br />
Tenemos así la clase PlanInvasionBoImpl que la implementa. Esta clase se comunica con un [[DAO]] para realizar la búsqueda del objeto de dominio Invasor. Luego de obtenerlo, lo convierte a un InvasorDto y lo devuelve.<br />
<br />
El Dao en cuestión es de la forma:<br />
<code java><br />
public interface PlanInvasionDao {<br />
public Invasor findInvasorById(Long id);<br />
}<br />
</code><br />
<br />
Usamos [[Spring Framework]] para inyectar la dependencia que tiene nuestro InvasorBoImpl con el Dao.<br />
<br />
As, nuestra clase InvasorBoImpl queda bastante simple:<br />
<code java><br />
public class PlanInvasionBoImpl implements PlanInvasionBo {<br />
<br />
private PlanInvasionDao planInvasionDao;<br />
<br />
public InvasorDto findInvasorById(Long id) {<br />
Invasor invasor = planInvasionDao.findInvasorById(id);<br />
InvasorDto invasorDto = new InvasorDto(invasor.getId(), invasor.getNombre());<br />
return invasorDto;<br />
}<br />
//Getters y setters de planInvasioDao a continuacion...<br />
}<br />
</code><br />
<br />
===Creando el test de PlanInvasioBoImpl===<br />
<br />
Crearemos entonces un test unitario usando [[JUnit]] para nuestro método ''PlanInvasioBoImpl.findInvasioById()''.<br />
<br />
Obviamente, no queremos testear a nuestro Dao (recordemos la definición de [[Prueba Unitaria]]!), así que deberemos crear un [[MockObject]] para simularlo.<br />
<br />
La creación de mocks es muy simple con EasyMock. Los pasos básicos son:<br />
<br />
# Crear el mock (usualmente, en el setUp() del test<br />
# "Grabarle" el comportamiento esperado<br />
# Iniciar el mock (a través del método replay())<br />
# Ejecutar nuestro método a testear<br />
# Verificar el mock (a través del método verify())<br />
# Realizar otros assert nuestros<br />
<br />
Así, nuestro test completo quedaría:<br />
<code java><br />
package test.com.dosideas.mock.business.impl;<br />
<br />
//imports varios...<br />
import static org.easymock.EasyMock.*;<br />
<br />
public class PlanInvasionBoImplTest extends TestCase {<br />
<br />
private PlanInvasionBoImpl planInvasionBo;<br />
private PlanInvasionDao mockDao;<br />
<br />
protected void setUp() throws Exception {<br />
mockDao = createMock(PlanInvasionDao.class);<br />
planInvasionBo = new PlanInvasionBoImpl();<br />
planInvasionBo.setPlanInvasionDao(mockDao);<br />
}<br />
<br />
public void testFindInvasorById() {<br />
Long id = 1L;<br />
Invasor invasor = new Invasor(id, "Zim");<br />
<br />
expect(mockDao.findInvasorById(id)).andReturn(invasor);<br />
replay(mockDao);<br />
<br />
InvasorDto resultado = planInvasionBo.findInvasorById(id);<br />
<br />
verify(mockDao);<br />
assertEquals(invasor.getId(), resultado.getId());<br />
assertEquals(invasor.getNombre(), resultado.getNombre());<br />
}<br />
}<br />
</code><br />
<br />
===Y lo que ocurre es lo siguiente...===<br />
Como vemos, realizamos un import static de varios métodos de la clase EasyMock (si, necesitamos JSE 5 para la última versión de EasyMock)<br />
<br />
En el método setUp() creamos el mock. Los mocks se crean a partir de interfaces. Así, le asignamos la dependencia a nuestro Bo a testear.<br />
<br />
Finalmente, ya en testFindInvasionById() y antes de ejecutar el método a testear, grabamos el comportamiento que deseamos de nuestro mock. La línea "expect(....)" puede leerse como:<br />
<br />
"Esperar que se invoque a mockDao.findInvasorById() con el parámetro id, y entonces devolver invasor".<br />
<br />
Por último, la llamada a "verify" verifica que se las invocaciones a nuestro mock hayan ocurrido, en el orden que dijimos.<br />
<br />
==Ver también==<br />
* [[EasyMock version 2.4]]<br />
* [[MockEjb]]<br />
* [[Prueba Unitaria]]<br />
* [http://www.easymock.org/ Web oficial de EasyMock]<br />
* [http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html Getting started with EasyMock2]</div>Zabalethttps://dosideas.com/wiki/index.php?title=JMS_Con_GlassFish&diff=1087JMS Con GlassFish2008-09-24T14:56:47Z<p>Zabalet: </p>
<hr />
<div>Para utilizar JMS con GlassFish es necesario incluir en el classpath del cliente los siguientes Jars que pueden encontrarse en el directorio de instalación de GlassFish:<br />
<code><br />
installDir/lib/appserv-rt.jar<br />
installDir/lib/j2ee.jar<br />
installDir/lib/install/aplications/jmsra/imqjmsra.jar<br />
</code><br />
Encontré también necesario incluir<br />
<code><br />
installDir/lib/appserv-admin.jar<br />
</code><br />
[https://glassfish.dev.java.net/nonav/javaee5/docs/DG/beakt.html#beali En la documentaci&oacute;n de GlassFish]</div>Zabalethttps://dosideas.com/wiki/index.php?title=JMS_Con_GlassFish&diff=1086JMS Con GlassFish2008-09-24T13:29:14Z<p>Zabalet: </p>
<hr />
<div>Para utilizar JMS con GlassFish es necesario incluir en el classpath del cliente los siguientes Jars que pueden encontrarse en el directorio de instalación de GlassFish:<br />
<code><br />
installDir/lib/appserv-rt.jar<br />
installDir/lib/j2ee.jar<br />
installDir/install/aplications/jmsra/imqjmsra.jar<br />
</code><br />
Encontré también necesario incluir<br />
<code><br />
installDir/lib/appserv-admin.jar<br />
</code><br />
[https://glassfish.dev.java.net/nonav/javaee5/docs/DG/beakt.html#beali En la documentaci&oacute;n de GlassFish]</div>Zabalethttps://dosideas.com/wiki/index.php?title=JMS_Con_GlassFish&diff=1085JMS Con GlassFish2008-09-24T13:28:14Z<p>Zabalet: </p>
<hr />
<div>Para utilizar JMS con GlassFish son necesarios los siguientes Jars que pueden encontrarse en el directorio de instalación de GlassFish:<br />
<code><br />
installDir/lib/appserv-rt.jar<br />
installDir/lib/j2ee.jar<br />
installDir/install/aplications/jmsra/imqjmsra.jar<br />
</code><br />
Encontré también necesario incluir<br />
<code><br />
installDir/lib/appserv-admin.jar<br />
</code><br />
[https://glassfish.dev.java.net/nonav/javaee5/docs/DG/beakt.html#beali En la documentaci&oacute;n de GlassFish]</div>Zabalethttps://dosideas.com/wiki/index.php?title=JMS&diff=1084JMS2008-09-24T13:10:27Z<p>Zabalet: /* Ver también */</p>
<hr />
<div>Java Messaging Service es un API de [[Java]] que permite interactuar con colas de mensajes.<br />
<br />
==Qué son las colas de mensajes==<br />
<br />
Supongamos que existen 2 aplicaciones, Dib y Gaz. Dib sabe comer, y Gaz sabe hacer tostadas.<br />
<br />
Cuando Dib tiene hambre, necesita realizarle un pedido a Gaz ("haceme 3 tostadas"). Usualmente, cuando Dib se levanta a la mañana le pide a Gaz las tostadas, y espera hasta que estén listas. Y este es el comportamiento que usamos generalmente en nuestras aplicaciones: al invocar a otra aplicacion nuestra, lo hacemos via un EJB, y esperamos una respuesta "en el momento" (sincrónica) de la operación.<br />
<br />
Ahora bien, hace unas semanas que Gaz consiguió un trabajo, así que no está durante toda la mañana. Y Dib estudia de noche y vuelve tarde, cuando Gaz ya está durmiendo. ¿Cómo comunicar entonces a estas dos aplicaciones, si ambas pueden no estar online en el mismo momento?<br />
<br />
La solución a esto sería que Dib dejara una "petición" en algún lado (¿un papelito en la heladera?), y Gaz lo leyera cuando tenga tiempo y pueda cocinar las tostadas para Dib.<br />
<br />
Justamente, esta comunicación asincrónica es el principio de la cola de mensajes.<br />
<br />
==La cola de mensajes==<br />
<br />
Una cola de mensajes es un lugar común (la heladera) donde algunas aplicaciones publican mensajes, que son consumidos por otras. Existen así 4 componentes principales en un sistema de mensajería:<br />
<br />
* publicador, es decir, quien publica un Mensaje en una Cola<br />
* consumidor, quien consume Mensajes de una Cola<br />
* mensaje, que tiene algún formato que tanto publicador como consumidor conocen.<br />
* cola, que es el lugar donde publicadores y consumidores se conectan y comunican a través de mensajes.<br />
<br />
Es importante destacar que es un sistema asíncrono: el publicador y el consumidor no necesitan estar disponibles a la vez, ya que la cola actúa de intermediario, guardando y distribuyendo los mensajes a medida que el consumidor pueda atenderlos.<br />
<br />
== El API de JMS==<br />
<br />
===Tipos de destinos===<br />
<br />
En JMS existen dos tipos de destinos: Queue (colas) y Topic.<br />
====Queue====<br />
<br />
En las Queue, existen uno o varios publicadores, y un consumidor. Los publicadores van dejando sus mensajes en la cola, y son tomados en orden por el consumidor (y luego se van descartando). Si el consumidor no está disponible, la cola va guardando ("encolando") los mensajes, de manera que el consumidor pueda retomar su procesamiento cuando vuelva a estar online.<br />
<br />
====Topic====<br />
Los Topic siguen el modelo "publicador/subscriptor". Uno o varios consumidores se "suscriben" al Topic, y van reciendo los mensajes que se publican. Cuando se desconectan dejan de recibir esos mensajes, y los pierden.<br />
<br />
==== Otros tipos de mensaje ====<br />
<br />
En el ejemplo, utilizamos un objeto !TextMessage para enviar el mensaje, pero existen otros tipos de mensaje muy útiles. Uno en particular es !MapMessage, que parmite al mensaje agregarle varios pares de "clave-valor" para luego recuperarlos. Además, existe otro mensaje de tipo !ObjectMessage que permite enviar un objeto completo (serializable) dentro del mensaje.<br />
<br />
== Ver también==<br />
* [[Ejemplo De JMS]]<br />
* [[JMS Con GlassFish]]<br />
* [[Herramientas JMS]]<br />
* [[Prioridad De Mensajes JMS]]<br />
* [[JMSCorrelationID]]<br />
* [[Mensajeria Con Spring]]<br />
* [http://www.programacion.com/java/articulo/jms/ Tutorial sobre JMS ]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Ejemplo_De_JMS&diff=1083Ejemplo De JMS2008-09-23T20:25:54Z<p>Zabalet: /* Creando nuestro Bean MDB */</p>
<hr />
<div>==Haciendo tostadas==<br />
<br />
Vamos entonces a hacer que nuestras aplicaciones Dib y Gaz se comuniquen con una cola de mensajes. Lo que haremos a continuación será:<br />
<br />
* Crear una cola en WebLogic (la heladera para pegar los mensajes)<br />
* Crear una aplicación que publique mensajes en la cola (Dib)<br />
* Crear un EJB que consuma los mensajes de la cola (Gaz)<br />
<br />
=== Creando la cola en WebLogic 8.1 ===<br />
<br />
Lo primero entonces será de crear la cola para que nuestras aplicaciones pueda interactuar. Para esto crearemos la cola propiamente dicho, y un factory que se conecte a la misma. Todo esto se realiza desde la consola de WebLogic.<br />
Creando el Connection Factory<br />
<br />
# Abran la consola de WebLogic<br />
# Vayan a Services -> JMS -> Connection Factories<br />
# Click en el link "Configure a new JMS Connection Factory..."<br />
# En el campo Name ponemos "Heladera Connection Factory"<br />
# En el campo JNDI Name ponemos "HeladeraCF".<br />
# Click en el botón "Create"<br />
<br />
Con esto tenemos creado un Connection Factory bajo el nombre JNDI de HeladeraCF. El publicador (Dib) utilizará este Connection Factory para tener acceso a la cola y poder publicar mensajes.<br />
Creando la cola<br />
<br />
# Vayan a Services -> JMS -> Servers<br />
# Abrir el nodo con el nombre similar a "WSStoreForwardInternalJMSServermyserver"<br />
# Click en el nodo "Destinations"<br />
# Click en "Configure a new JMS Queue..."<br />
# En el campo Name ponemos "Heladera Queue"<br />
# En el campo JNDI Name ponemos "HeladeraQueue"<br />
# Click en el botón "Create"<br />
<br />
Con esto tendremos creada la cola de mensajes bajo el nombre JNDI !HeladeraQueue. Así, Dib podrá publicar mensajes aquí, que luego serán tomados por Gaz.<br />
<br />
=== Dib pega mensajitos en la Heladera ===<br />
... o lo que es lo mismo, vamos a crear una aplicación que se conecte a la cola y postee mensajes.<br />
<br />
Vamos entonces a hacer una clase muy simple que tenga un método "pedirTostadas" que se conecte a la cola y envie un mensaje de texto indicando cuantas tostadas queremos.<br />
<br />
<code java><br />
import javax.jms.*;<br />
<br />
public class Dib {<br />
public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";<br />
public final static String PROVIDER_URL="t3://localhost";<br />
<br />
public final static String JMS_FACTORY="!HeladeraCF";<br />
public final static String QUEUE="HeladeraQueue";<br />
<br />
public void pedirTostadas() {<br />
//Obtenemos el InitialContext<br />
Hashtable env = new Hashtable();<br />
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);<br />
env.put(Context.PROVIDER_URL, PROVIDER_URL);<br />
InitialContext ctx = new InitialContext(env);<br />
<br />
//Buscamos el factory y la conexion a la cola<br />
QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);<br />
QueueConnection qcon = qconFactory.createQueueConnection();<br />
<br />
//Buscamos la cola<br />
QueueSession qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);<br />
Queue queue = (Queue) ctx.lookup(QUEUE);<br />
<br />
//Creamos el mensaje<br />
TextMessage msg = qsession.createTextMessage();<br />
msg.setText("Gaz, quiero 4 tostadas");<br />
<br />
//Enviamos el mensaje<br />
QueueSender qsender = qsession.createSender(queue);<br />
qsender.send(msg);<br />
<br />
//somos prolijos y cerramos todo<br />
qsender.close();<br />
qsession.close();<br />
qcon.close();<br />
}<br />
}<br />
</code><br />
<br />
Para enviar mensajes a la cola, basta con ejecutar:<br />
<code java><br />
Dib dib = new Dib();<br />
dib.pedirTostadas();<br />
</code><br />
<br />
Con esto, Dib enviará un mensaje a la cola (HeladeraQueue). Ahora, no hay nadie consumiendo de dicha cola, por lo cual los mensajes se iran acumulando. Así que vayamos a despertar a Gaz para que pueda ayudar a su hermano...<br />
Gaz hace las tostadas<br />
<br />
Nos queda entonces consumir los mensajes de una cola. La manera más facil de consumir mensajes es a través de un EJB MDB (Message-Driven Bean). Los EJB MDB son un tipo especial de EJB que cumplen con un único método: onMessage(Message msg)<br />
<br />
El método onMessage se invoca cada vez que hay algún mensaje para atender. En la configuración del EJB (los queridos descriptores) se le indica a qué cola está asociado el EJB.<br />
<br />
Crearemos entonces a Gaz como un EJB MDB. Para esto podremos usar algún módulo EJB de Bacabs.<br />
<br />
=== Creando nuestro Bean MDB ===<br />
<br />
Un EJB MDB está compuesto por una única clase que implementa las interfaces MessageDrivenBean y MessageListener. Creemos entonces nuestro EJB:<br />
<br />
<code java><br />
public class GazMDBBean implements MessageDrivenBean, MessageListener {<br />
<br />
public void setMessageDrivenContext(MessageDrivenContext aContext) {<br />
context = aContext;<br />
}<br />
<br />
public void ejbCreate() { }<br />
public void ejbRemove() { }<br />
<br />
public void onMessage(Message aMessage) {<br />
TextMessage txtMessage = (TextMessage) aMessage;<br />
String mensajeDeDib = txtMessage.getText();<br />
System.out.println(mensajeDeDib);<br />
}<br />
}<br />
</code><br />
<br />
Y esto es todo lo que programaremos para atender el mensaje. Simple, no? Bueno, en realidad falta la magia de los XML.<br />
<br />
=== Creando el ejb-jar.xml ===<br />
<br />
Como todo EJB2, necesita de su descriptor correspondiente. El mismo es bastante simple:<br />
<br />
<code xml><br />
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"><br />
<br />
<ejb-jar><br />
<display-name>Gaz MDB</display-name><br />
<br />
<enterprise-beans><br />
<message-driven><br />
<ejb-name>GazMDBBean</ejb-name><br />
<ejb-class>com.zim.mdb.GazMDBBean</ejb-class><br />
<transaction-type>Container</transaction-type><br />
<message-driven-destination><br />
<destination-type>javax.jms.Queue</destination-type><br />
</message-driven-destination><br />
</message-driven><br />
</enterprise-beans><br />
<br />
<assembly-descriptor><br />
<container-transaction><br />
<method><br />
<ejb-name>GazMDBBean</ejb-name><br />
<method-name>*</method-name><br />
</method><br />
<trans-attribute>Required</trans-attribute><br />
</container-transaction><br />
</assembly-descriptor><br />
</ejb-jar><br />
</code><br />
<br />
===Creando el weblogic-ejb-jar.xml===<br />
<br />
Y como todo EJB que hacemos para WebLogic, este es el descriptor hermanito del anterior. Contiene configuración propia para WebLogic, y los datos de la cola de la cual consumirá mensajes nuestro EJB MDB. El archivo es muy simple:<br />
<br />
<code xml><br />
<?xml version="1.0"?><br />
<!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN" "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd"><br />
<br />
<weblogic-ejb-jar><br />
<weblogic-enterprise-bean><br />
<ejb-name>GazMDBBean</ejb-name><br />
<message-driven-descriptor><br />
<pool><br />
<max-beans-in-free-pool>200</max-beans-in-free-pool><br />
<initial-beans-in-free-pool>20</initial-beans-in-free-pool><br />
</pool><br />
<destination-jndi-name>!HeladeraQueue</destination-jndi-name><br />
</message-driven-descriptor><br />
<enable-call-by-reference>True</enable-call-by-reference><br />
</weblogic-enterprise-bean><br />
<br />
</weblogic-ejb-jar><br />
</code><br />
<br />
En el tag destination-jndi-name indicamos la cola de la cual consumirá mensajes nuestro EJB.<br />
<br />
===Probando (finalmente)===<br />
<br />
Empaquetamos y hacemos un deploy de nuestro EJB en WebLogic, y el mismo comenzará a consumir los mensajes de la cola automágicamente.<br />
<br />
No solo consumirá los mensajes nuevos, sino también todos aquellos que hayan quedado encolados sin procesar.<br />
<br />
Prueben generar muchos mensajes con Dib, y vean como se van procesando. O hagan un stop de Gaz, y vean como al volver a levantarlo procesa todos los mensajes que fueron encolado.<br />
<br />
==Consumiendo mensajes con JMS==<br />
<br />
El API de JMS nos da tambien las herramientas para consumir los mensajes de dicha cola. A continuación un ejemplo sencillo de como hacerlo.<br />
<br />
===Ahora cocinamos las tostadas===<br />
<br />
Vamos a seguir con el ejemplo dado anteriormente<br />
<br />
Se quiere cocinar las tostadas que pidio Dib, sin utilizar a Gaz (EJB) dado a que no las prepara del todo bien (amarretea con la mermelada). El competidor para cocinar es Tak (tuve que buscar personajes de la serie). Con un código similar al que Dib utilizaba para pedir las tostadas, aca esta el ejemplo:<br />
<br />
<code java><br />
import javax.jms.*;<br />
<br />
public class Tak {<br />
<br />
public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";<br />
public final static String PROVIDER_URL = "t3://localhost:7001";<br />
public final static String JMS_FACTORY = "HeladeraCF";<br />
public final static String QUEUE = "HeladeraQueue";<br />
<br />
public TextMessage cocinarTostadas() throws NamingException, JMSException {<br />
// Obtenemos el InitialContext<br />
Hashtable env = new Hashtable();<br />
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);<br />
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);<br />
env.put(Context.PROVIDER_URL, PROVIDER_URL);<br />
InitialContext ctx = new InitialContext(env);<br />
<br />
// Buscamos el factory y la conexion a la cola<br />
QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);<br />
QueueConnection qcon = qconFactory.createQueueConnection();<br />
<br />
// Buscamos la cola<br />
QueueSession qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);<br />
Queue queue = (Queue) ctx.lookup(AUTO_ACKNOWLEDGE);<br />
Queue queue = (Queue) ctx.lookup(QUEUE);<br />
<br />
QueueReceiver qreceiver = qsession.createReceiver(queue);<br />
<br />
//"Inicio" la QueueConnection<br />
qcon.start();<br />
TextMessage msg = (TextMessage) qreceiver.receive();<br />
<br />
qreceiver.close();<br />
qsession.close();<br />
qcon.close();<br />
return msg;<br />
}<br />
}<br />
</code><br />
<br />
<br />
La unica diferencia con Dib es que se crea un Receiver, que va a ir a buscar los mensajes a la cola. Y ademas hay que darle un start a la QueueConnection.<br />
<br />
===Testear la coccion de tostadas===<br />
<br />
Para testear la coccion de tostadas:<br />
<br />
<code java><br />
public void testCocinarTostada() throws NamingException, JMSException{<br />
<br />
Tak tak = new Tak();<br />
TextMessage txtMessage = tak.cocinarTostadas();<br />
<br />
String mensajeDeDib;<br />
<br />
try {<br />
mensajeDeDib = txtMessage.getText();<br />
System.out.println(mensajeDeDib);<br />
txtMessage.acknowledge();<br />
} catch (JMSException e) {<br />
e.printStackTrace();<br />
}<br />
}<br />
</code><br />
<br />
Claro que antes de correr el test, la cola debe tener algun mensaje, sino se va a quedar esperando en el receive() hasta que la cola tenga alguno. Esto se puede evitar usando:<br />
<br />
*receive(long i) : Espera por un mensaje i milisegundos.<br />
*receiveNotWait() : Si no hay mensajes, no se queda esperando.<br />
<br />
Y un agregado mas: En el caso de que hayan probado hacer el EJB para consumir la cola, tengan el detalle de bajarlo del server, porque si no cuando subamos un mensaje a la cola, probablemente se lo lleve el EJB antes que Tak.<br />
<br />
<br />
== Ver también==<br />
* [[JMS]]<br />
* [[MDB En WebLogic]]<br />
* [[JMS Con GlassFish]]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Sandbox&diff=1082Sandbox2008-09-23T20:18:56Z<p>Zabalet: </p>
<hr />
<div>Página de prueba para jugar. Hacer click en "editar" en la parte superior para ver el código de esta página, editar y hacer pruebas.<br />
<br />
Otra linea.<br />
<br />
==Un título de nivel 1==<br />
Recordar no usar títulos con un sólo igual (=titulo aca=), ya que los pone al mismo nivel que el titulo de la página. <br />
<br />
===Un título de nivel 2===<br />
cuando en toda la página hay más de 3 títulos (de cualquier nivel) se genera automáticamente una tabla de contenidos.<br />
<br />
====Un título de nivel 3====<br />
y así...<br />
<br />
===Ejemplo de links a la propia Wiki===<br />
Los links internos se ponen con doble corchete [[Portada]]. Si la página no existe, aparece el link en rojo: [[Esta pagina no existe]].<br />
<br />
Los links externos se ponen con corchete simple, de la siguiente forma: [http://www.google.com El sitio de Google]. La descripción es opcional en estos links: http://www.dosideas.com<br />
<br />
=== Código ===<br />
Líneas de código se pueden encerar entre los tags PRE<br />
<pre><br />
public class Ejemplo {<br />
private Long id;<br />
private String nombre;<br />
...<br />
}<br />
</pre><br />
<br />
También se logra lo mismo empezando la oración con un espacio: <br />
public class Ejemplo {<br />
private Long id;<br />
private String nombre;<br />
...<br />
}<br />
<br />
Se puede encerrar texto entre el tag NOWIKI, lo cual evita que se creen links y otras características de la wiki: <br />
<pre><br />
<nowiki><br />
Este texto está como codigo, y además las URL no se linkean: www.dosideas.com<br />
</nowiki><br />
</pre><br />
<br />
===Ejemplo de listas===<br />
* lista sin numerar<br />
* lista sin numerar<br />
** lista sin numerar subitem<br />
** lista sin numerar subitem<br />
*** lista sin numerar sub-subitem<br />
*** lista sin numerar sub-subitem<br />
* ultimo item<br />
<br />
# lista numerada<br />
# lista numerada<br />
## lista numerada<br />
## lista numerada<br />
# ultimo elemento<br />
<br />
<br />
===Plantillas===<br />
{{aviso|texto=Este es un aviso normal. Aca se puede poner cualquier texto, y será destacado.}}<br />
<br />
{{curso|url=http://cursos.dosideas.com/course/view.php?id=4|nombre=Introducción al desarrollo Java EE}}<br />
<br />
== Codigo ==<br />
Mas info en: [http://www.mediawiki.org/wiki/Extension:GeSHiCodeTag], [http://qbnz.com/highlighter/]<br />
<br />
==== Codigo Java5 ====<br />
<code java5><br />
import java.util.Collection;<br />
<br />
public class Alumno extends Persona {<br />
private String nombre;<br />
private Long id;<br />
<br />
public String getNombre() {<br />
return nombre;<br />
}<br />
}<br />
</code><br />
<br />
==== Codigo XML ====<br />
<code xml><br />
<persona><br />
<nombre>Zim</nombre><br />
<ocupacion>Invasor</ocupacion><br />
</persona><br />
</code><br />
<br />
==Imagenes como links==<br />
<br />
{| width="80%" align="center" border="0"<br />
|-<br />
| <imagemap><br />
Image:Desarrollo-de-software.jpg|center|Desarrollo de software<br />
default [[Desarrollo De Software]]<br />
desc none<br />
</imagemap> <br />
<p align="center" style="font-size:large">'''[[Desarrollo De Software]]'''</p><br />
|| <imagemap><br />
Image:Metodologias-de-desarollo.jpg|center|Metodologias de desarrollo<br />
default [[Metodologias De Desarrollo]]<br />
desc none<br />
</imagemap><br />
<p align="center" style="font-size:large">'''[[Metodologias De Desarrollo]]'''</p><br />
|}<br />
<br />
==Ayuda general==<br />
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]<br />
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]<br />
* [http://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]<br />
* [http://meta.wikimedia.org/wiki/Help:Contents Guía de uso de MediaWiki]</div>Zabalethttps://dosideas.com/wiki/index.php?title=Sandbox&diff=1081Sandbox2008-09-23T20:18:29Z<p>Zabalet: </p>
<hr />
<div>Página de prueba para jugar. Hacer click en "editar" en la parte superior para ver el código de esta página, editar y hacer pruebas.<br />
<br />
Otra linea.<br />
<br />
=QUe nivel tiene este titulo=<br />
<br />
==Un título de nivel 1==<br />
Recordar no usar títulos con un sólo igual (=titulo aca=), ya que los pone al mismo nivel que el titulo de la página. <br />
<br />
===Un título de nivel 2===<br />
cuando en toda la página hay más de 3 títulos (de cualquier nivel) se genera automáticamente una tabla de contenidos.<br />
<br />
====Un título de nivel 3====<br />
y así...<br />
<br />
===Ejemplo de links a la propia Wiki===<br />
Los links internos se ponen con doble corchete [[Portada]]. Si la página no existe, aparece el link en rojo: [[Esta pagina no existe]].<br />
<br />
Los links externos se ponen con corchete simple, de la siguiente forma: [http://www.google.com El sitio de Google]. La descripción es opcional en estos links: http://www.dosideas.com<br />
<br />
=== Código ===<br />
Líneas de código se pueden encerar entre los tags PRE<br />
<pre><br />
public class Ejemplo {<br />
private Long id;<br />
private String nombre;<br />
...<br />
}<br />
</pre><br />
<br />
También se logra lo mismo empezando la oración con un espacio: <br />
public class Ejemplo {<br />
private Long id;<br />
private String nombre;<br />
...<br />
}<br />
<br />
Se puede encerrar texto entre el tag NOWIKI, lo cual evita que se creen links y otras características de la wiki: <br />
<pre><br />
<nowiki><br />
Este texto está como codigo, y además las URL no se linkean: www.dosideas.com<br />
</nowiki><br />
</pre><br />
<br />
===Ejemplo de listas===<br />
* lista sin numerar<br />
* lista sin numerar<br />
** lista sin numerar subitem<br />
** lista sin numerar subitem<br />
*** lista sin numerar sub-subitem<br />
*** lista sin numerar sub-subitem<br />
* ultimo item<br />
<br />
# lista numerada<br />
# lista numerada<br />
## lista numerada<br />
## lista numerada<br />
# ultimo elemento<br />
<br />
<br />
===Plantillas===<br />
{{aviso|texto=Este es un aviso normal. Aca se puede poner cualquier texto, y será destacado.}}<br />
<br />
{{curso|url=http://cursos.dosideas.com/course/view.php?id=4|nombre=Introducción al desarrollo Java EE}}<br />
<br />
== Codigo ==<br />
Mas info en: [http://www.mediawiki.org/wiki/Extension:GeSHiCodeTag], [http://qbnz.com/highlighter/]<br />
<br />
==== Codigo Java5 ====<br />
<code java5><br />
import java.util.Collection;<br />
<br />
public class Alumno extends Persona {<br />
private String nombre;<br />
private Long id;<br />
<br />
public String getNombre() {<br />
return nombre;<br />
}<br />
}<br />
</code><br />
<br />
==== Codigo XML ====<br />
<code xml><br />
<persona><br />
<nombre>Zim</nombre><br />
<ocupacion>Invasor</ocupacion><br />
</persona><br />
</code><br />
<br />
==Imagenes como links==<br />
<br />
{| width="80%" align="center" border="0"<br />
|-<br />
| <imagemap><br />
Image:Desarrollo-de-software.jpg|center|Desarrollo de software<br />
default [[Desarrollo De Software]]<br />
desc none<br />
</imagemap> <br />
<p align="center" style="font-size:large">'''[[Desarrollo De Software]]'''</p><br />
|| <imagemap><br />
Image:Metodologias-de-desarollo.jpg|center|Metodologias de desarrollo<br />
default [[Metodologias De Desarrollo]]<br />
desc none<br />
</imagemap><br />
<p align="center" style="font-size:large">'''[[Metodologias De Desarrollo]]'''</p><br />
|}<br />
<br />
==Ayuda general==<br />
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]<br />
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]<br />
* [http://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]<br />
* [http://meta.wikimedia.org/wiki/Help:Contents Guía de uso de MediaWiki]</div>Zabalethttps://dosideas.com/wiki/index.php?title=JMS_Con_GlassFish&diff=1080JMS Con GlassFish2008-09-23T20:11:42Z<p>Zabalet: </p>
<hr />
<div><code>appserv-rt.jar - available at install-dir/lib<br />
j2ee.jar - available at install-dir/lib<br />
imqjmsra.jar - available at install-dir/lib/install/aplications/jmsra</code><br />
[https://glassfish.dev.java.net/nonav/javaee5/docs/DG/beakt.html#beali En la documentaci&oacute;n de GlassFish]</div>Zabalethttps://dosideas.com/wiki/index.php?title=JMS_Con_GlassFish&diff=1079JMS Con GlassFish2008-09-23T20:11:01Z<p>Zabalet: </p>
<hr />
<div><code><br />
appserv-rt.jar - available at install-dir/lib<br />
j2ee.jar - available at install-dir/lib<br />
imqjmsra.jar - available at install-dir/lib/install/aplications/jmsra<br />
</code><br />
[https://glassfish.dev.java.net/nonav/javaee5/docs/DG/beakt.html#beali En la documentaci&oacute;n de GlassFish]</div>Zabalethttps://dosideas.com/wiki/index.php?title=JMS_Con_GlassFish&diff=1078JMS Con GlassFish2008-09-23T20:06:14Z<p>Zabalet: Página nueva: <code> appserv-rt.jar - available at install-dir/lib j2ee.jar - available at install-dir/lib imqjmsra.jar - available at install-dir/lib/install/aplications/jmsra </code></p>
<hr />
<div><code><br />
appserv-rt.jar - available at install-dir/lib<br />
j2ee.jar - available at install-dir/lib<br />
imqjmsra.jar - available at install-dir/lib/install/aplications/jmsra<br />
</code></div>Zabalethttps://dosideas.com/wiki/index.php?title=Ejemplo_De_JMS&diff=1077Ejemplo De JMS2008-09-23T20:03:58Z<p>Zabalet: /* Ver también */</p>
<hr />
<div>==Haciendo tostadas==<br />
<br />
Vamos entonces a hacer que nuestras aplicaciones Dib y Gaz se comuniquen con una cola de mensajes. Lo que haremos a continuación será:<br />
<br />
* Crear una cola en WebLogic (la heladera para pegar los mensajes)<br />
* Crear una aplicación que publique mensajes en la cola (Dib)<br />
* Crear un EJB que consuma los mensajes de la cola (Gaz)<br />
<br />
=== Creando la cola en WebLogic 8.1 ===<br />
<br />
Lo primero entonces será de crear la cola para que nuestras aplicaciones pueda interactuar. Para esto crearemos la cola propiamente dicho, y un factory que se conecte a la misma. Todo esto se realiza desde la consola de WebLogic.<br />
Creando el Connection Factory<br />
<br />
# Abran la consola de WebLogic<br />
# Vayan a Services -> JMS -> Connection Factories<br />
# Click en el link "Configure a new JMS Connection Factory..."<br />
# En el campo Name ponemos "Heladera Connection Factory"<br />
# En el campo JNDI Name ponemos "HeladeraCF".<br />
# Click en el botón "Create"<br />
<br />
Con esto tenemos creado un Connection Factory bajo el nombre JNDI de HeladeraCF. El publicador (Dib) utilizará este Connection Factory para tener acceso a la cola y poder publicar mensajes.<br />
Creando la cola<br />
<br />
# Vayan a Services -> JMS -> Servers<br />
# Abrir el nodo con el nombre similar a "WSStoreForwardInternalJMSServermyserver"<br />
# Click en el nodo "Destinations"<br />
# Click en "Configure a new JMS Queue..."<br />
# En el campo Name ponemos "Heladera Queue"<br />
# En el campo JNDI Name ponemos "HeladeraQueue"<br />
# Click en el botón "Create"<br />
<br />
Con esto tendremos creada la cola de mensajes bajo el nombre JNDI !HeladeraQueue. Así, Dib podrá publicar mensajes aquí, que luego serán tomados por Gaz.<br />
<br />
=== Dib pega mensajitos en la Heladera ===<br />
... o lo que es lo mismo, vamos a crear una aplicación que se conecte a la cola y postee mensajes.<br />
<br />
Vamos entonces a hacer una clase muy simple que tenga un método "pedirTostadas" que se conecte a la cola y envie un mensaje de texto indicando cuantas tostadas queremos.<br />
<br />
<code java><br />
import javax.jms.*;<br />
<br />
public class Dib {<br />
public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";<br />
public final static String PROVIDER_URL="t3://localhost";<br />
<br />
public final static String JMS_FACTORY="!HeladeraCF";<br />
public final static String QUEUE="HeladeraQueue";<br />
<br />
public void pedirTostadas() {<br />
//Obtenemos el InitialContext<br />
Hashtable env = new Hashtable();<br />
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);<br />
env.put(Context.PROVIDER_URL, PROVIDER_URL);<br />
InitialContext ctx = new InitialContext(env);<br />
<br />
//Buscamos el factory y la conexion a la cola<br />
QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);<br />
QueueConnection qcon = qconFactory.createQueueConnection();<br />
<br />
//Buscamos la cola<br />
QueueSession qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);<br />
Queue queue = (Queue) ctx.lookup(QUEUE);<br />
<br />
//Creamos el mensaje<br />
TextMessage msg = qsession.createTextMessage();<br />
msg.setText("Gaz, quiero 4 tostadas");<br />
<br />
//Enviamos el mensaje<br />
QueueSender qsender = qsession.createSender(queue);<br />
qsender.send(msg);<br />
<br />
//somos prolijos y cerramos todo<br />
qsender.close();<br />
qsession.close();<br />
qcon.close();<br />
}<br />
}<br />
</code><br />
<br />
Para enviar mensajes a la cola, basta con ejecutar:<br />
<code java><br />
Dib dib = new Dib();<br />
dib.pedirTostadas();<br />
</code><br />
<br />
Con esto, Dib enviará un mensaje a la cola (HeladeraQueue). Ahora, no hay nadie consumiendo de dicha cola, por lo cual los mensajes se iran acumulando. Así que vayamos a despertar a Gaz para que pueda ayudar a su hermano...<br />
Gaz hace las tostadas<br />
<br />
Nos queda entonces consumir los mensajes de una cola. La manera más facil de consumir mensajes es a través de un EJB MDB (Message-Driven Bean). Los EJB MDB son un tipo especial de EJB que cumplen con un único método: onMessage(Message msg)<br />
<br />
El método onMessage se invoca cada vez que hay algún mensaje para atender. En la configuración del EJB (los queridos descriptores) se le indica a qué cola está asociado el EJB.<br />
<br />
Crearemos entonces a Gaz como un EJB MDB. Para esto podremos usar algún módulo EJB de Bacabs.<br />
<br />
=== Creando nuestro Bean MDB ===<br />
<br />
Un EJB MDB está compuesto por una única clase que implementa las interfaces MessageDrivenBean y MessageListener. Creemos entonces nuestro EJB:<br />
<br />
<code java><br />
public class GazMDBBean implements MessageDrivenBean, MessageListener {<br />
<br />
public void setMessageDrivenContext(MessageDrivenContext aContext) {<br />
context = aContext;<br />
}<br />
<br />
public void ejbCreate() { }<br />
public void ejbRemove() { }<br />
<br />
public void onMessage(Message aMessage) {<br />
TestMessage txtMessage = (TextMessage) aMessage;<br />
String mensajeDeDib = txtMessage.getText();<br />
System.out.println(mensajeDeDib);<br />
}<br />
}<br />
</code><br />
<br />
Y esto es todo lo que programaremos para atender el mensaje. Simple, no? Bueno, en realidad falta la magia de los XML.<br />
<br />
=== Creando el ejb-jar.xml ===<br />
<br />
Como todo EJB2, necesita de su descriptor correspondiente. El mismo es bastante simple:<br />
<br />
<code xml><br />
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"><br />
<br />
<ejb-jar><br />
<display-name>Gaz MDB</display-name><br />
<br />
<enterprise-beans><br />
<message-driven><br />
<ejb-name>GazMDBBean</ejb-name><br />
<ejb-class>com.zim.mdb.GazMDBBean</ejb-class><br />
<transaction-type>Container</transaction-type><br />
<message-driven-destination><br />
<destination-type>javax.jms.Queue</destination-type><br />
</message-driven-destination><br />
</message-driven><br />
</enterprise-beans><br />
<br />
<assembly-descriptor><br />
<container-transaction><br />
<method><br />
<ejb-name>GazMDBBean</ejb-name><br />
<method-name>*</method-name><br />
</method><br />
<trans-attribute>Required</trans-attribute><br />
</container-transaction><br />
</assembly-descriptor><br />
</ejb-jar><br />
</code><br />
<br />
===Creando el weblogic-ejb-jar.xml===<br />
<br />
Y como todo EJB que hacemos para WebLogic, este es el descriptor hermanito del anterior. Contiene configuración propia para WebLogic, y los datos de la cola de la cual consumirá mensajes nuestro EJB MDB. El archivo es muy simple:<br />
<br />
<code xml><br />
<?xml version="1.0"?><br />
<!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN" "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd"><br />
<br />
<weblogic-ejb-jar><br />
<weblogic-enterprise-bean><br />
<ejb-name>GazMDBBean</ejb-name><br />
<message-driven-descriptor><br />
<pool><br />
<max-beans-in-free-pool>200</max-beans-in-free-pool><br />
<initial-beans-in-free-pool>20</initial-beans-in-free-pool><br />
</pool><br />
<destination-jndi-name>!HeladeraQueue</destination-jndi-name><br />
</message-driven-descriptor><br />
<enable-call-by-reference>True</enable-call-by-reference><br />
</weblogic-enterprise-bean><br />
<br />
</weblogic-ejb-jar><br />
</code><br />
<br />
En el tag destination-jndi-name indicamos la cola de la cual consumirá mensajes nuestro EJB.<br />
<br />
===Probando (finalmente)===<br />
<br />
Empaquetamos y hacemos un deploy de nuestro EJB en WebLogic, y el mismo comenzará a consumir los mensajes de la cola automágicamente.<br />
<br />
No solo consumirá los mensajes nuevos, sino también todos aquellos que hayan quedado encolados sin procesar.<br />
<br />
Prueben generar muchos mensajes con Dib, y vean como se van procesando. O hagan un stop de Gaz, y vean como al volver a levantarlo procesa todos los mensajes que fueron encolado.<br />
<br />
==Consumiendo mensajes con JMS==<br />
<br />
El API de JMS nos da tambien las herramientas para consumir los mensajes de dicha cola. A continuación un ejemplo sencillo de como hacerlo.<br />
<br />
===Ahora cocinamos las tostadas===<br />
<br />
Vamos a seguir con el ejemplo dado anteriormente<br />
<br />
Se quiere cocinar las tostadas que pidio Dib, sin utilizar a Gaz (EJB) dado a que no las prepara del todo bien (amarretea con la mermelada). El competidor para cocinar es Tak (tuve que buscar personajes de la serie). Con un código similar al que Dib utilizaba para pedir las tostadas, aca esta el ejemplo:<br />
<br />
<code java><br />
import javax.jms.*;<br />
<br />
public class Tak {<br />
<br />
public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";<br />
public final static String PROVIDER_URL = "t3://localhost:7001";<br />
public final static String JMS_FACTORY = "HeladeraCF";<br />
public final static String QUEUE = "HeladeraQueue";<br />
<br />
public TextMessage cocinarTostadas() throws NamingException, JMSException {<br />
// Obtenemos el InitialContext<br />
Hashtable env = new Hashtable();<br />
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);<br />
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);<br />
env.put(Context.PROVIDER_URL, PROVIDER_URL);<br />
InitialContext ctx = new InitialContext(env);<br />
<br />
// Buscamos el factory y la conexion a la cola<br />
QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);<br />
QueueConnection qcon = qconFactory.createQueueConnection();<br />
<br />
// Buscamos la cola<br />
QueueSession qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);<br />
Queue queue = (Queue) ctx.lookup(AUTO_ACKNOWLEDGE);<br />
Queue queue = (Queue) ctx.lookup(QUEUE);<br />
<br />
QueueReceiver qreceiver = qsession.createReceiver(queue);<br />
<br />
//"Inicio" la QueueConnection<br />
qcon.start();<br />
TextMessage msg = (TextMessage) qreceiver.receive();<br />
<br />
qreceiver.close();<br />
qsession.close();<br />
qcon.close();<br />
return msg;<br />
}<br />
}<br />
</code><br />
<br />
<br />
La unica diferencia con Dib es que se crea un Receiver, que va a ir a buscar los mensajes a la cola. Y ademas hay que darle un start a la QueueConnection.<br />
<br />
===Testear la coccion de tostadas===<br />
<br />
Para testear la coccion de tostadas:<br />
<br />
<code java><br />
public void testCocinarTostada() throws NamingException, JMSException{<br />
<br />
Tak tak = new Tak();<br />
TextMessage txtMessage = tak.cocinarTostadas();<br />
<br />
String mensajeDeDib;<br />
<br />
try {<br />
mensajeDeDib = txtMessage.getText();<br />
System.out.println(mensajeDeDib);<br />
txtMessage.acknowledge();<br />
} catch (JMSException e) {<br />
e.printStackTrace();<br />
}<br />
}<br />
</code><br />
<br />
Claro que antes de correr el test, la cola debe tener algun mensaje, sino se va a quedar esperando en el receive() hasta que la cola tenga alguno. Esto se puede evitar usando:<br />
<br />
*receive(long i) : Espera por un mensaje i milisegundos.<br />
*receiveNotWait() : Si no hay mensajes, no se queda esperando.<br />
<br />
Y un agregado mas: En el caso de que hayan probado hacer el EJB para consumir la cola, tengan el detalle de bajarlo del server, porque si no cuando subamos un mensaje a la cola, probablemente se lo lleve el EJB antes que Tak.<br />
<br />
<br />
== Ver también==<br />
* [[JMS]]<br />
* [[MDB En WebLogic]]<br />
* [[JMS Con GlassFish]]</div>Zabalet